{"_id":"@develate/quasar-app-extension-quasar-ext-components","_rev":"3-09e4ebdd3780b9c283ce3713400f8e9c","name":"@develate/quasar-app-extension-quasar-ext-components","dist-tags":{"latest":"1.1.0"},"versions":{"0.0.1":{"name":"@develate/quasar-app-extension-quasar-ext-components","version":"0.0.1","keywords":["quasar","quasar-app-extension","quasar-app-vite","quasar-cli","vue","vuejs"],"author":{"name":"Thorsten","email":"tk@programmierung.deutschehandarbeit.de"},"license":"MIT","_id":"@develate/quasar-app-extension-quasar-ext-components@0.0.1","maintainers":[{"name":"thoasty","email":"thorsten@thoasty.de"}],"homepage":"https://github.com/develate/quasar-ext-components#readme","bugs":{"url":"https://github.com/develate/quasar-ext-components/issues"},"dist":{"shasum":"bffcb7a96f86db59e8ff11355b2c2c2586a74186","tarball":"https://registry.npmjs.org/@develate/quasar-app-extension-quasar-ext-components/-/quasar-app-extension-quasar-ext-components-0.0.1.tgz","fileCount":19,"integrity":"sha512-QeXl8dX1fL73FgYCrYaFGWRTADWaqwL+wqTeFe7Q2DmlAME5/0/iUPAZzFNF6G7pSlMTExUToWq0qVBrHIi84g==","signatures":[{"sig":"MEUCIQCt7XzPPD2F2uaB0vvEJf/9QBv9oFy3lYN5BXSBw2KddwIgHuPdYkCbwi9OO/UKLMl+0yod+W2Nz7pJpKx1QZAY/+E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113029},"main":"src/index.ts","type":"module","engines":{"node":">= 26 || ^24 || ^22.12"},"gitHead":"ae15a36b0884591449d369290e19cbf2ed04e30d","imports":{"#q-app":"@quasar/app-vite"},"_npmUser":{"name":"thoasty","email":"thorsten@thoasty.de"},"repository":{"url":"git+https://github.com/develate/quasar-ext-components.git","type":"git","directory":"ae"},"_npmVersion":"9.6.4","description":"A Quasar App Extension","directories":{},"_nodeVersion":"14.18.1","dependencies":{"@clack/prompts":"^1.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"catalog:","quasar":"catalog:","@quasar/app-vite":"catalog:"},"peerDependencies":{"@quasar/app-vite":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/quasar-app-extension-quasar-ext-components_0.0.1_1785956203650_0.18077687536790976","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@develate/quasar-app-extension-quasar-ext-components","version":"0.0.2","keywords":["quasar","quasar-app-extension","quasar-app-vite","quasar-cli","vue","vuejs"],"author":"Thorsten <tk@programmierung.deutschehandarbeit.de>","license":"MIT","_id":"@develate/quasar-app-extension-quasar-ext-components@0.0.2","maintainers":[{"name":"thoasty","email":"thorsten@thoasty.de"}],"homepage":"https://github.com/develate/quasar-ext-components#readme","bugs":"https://github.com/develate/quasar-ext-components/issues","dist":{"shasum":"d86998b60296da59b226bd20068ce783f912a33a","tarball":"https://registry.npmjs.org/@develate/quasar-app-extension-quasar-ext-components/-/quasar-app-extension-quasar-ext-components-0.0.2.tgz","fileCount":23,"integrity":"sha512-12a91p6er4CUrl0ltlIGACeMctBZh4JXCihyyik2pNYrNRx/OSVYGvNu4VTxzJCjGq3/NcKAyg3LhPQVuFeUWg==","signatures":[{"sig":"MEQCIEoWPWppTnOhJC6WfFE4s7J5qe6suDgCM2kwrdCpj5CXAiB9l8GWNu97NzMUCBc7sopYTw5CCSNIzJkGtnduvk9rWw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":200135},"main":"src/index.ts","type":"module","engines":{"node":">= 26 || ^24 || ^22.12"},"imports":{"#q-app":"@quasar/app-vite"},"_npmUser":{"name":"thoasty","email":"thorsten@thoasty.de"},"repository":{"url":"git+https://github.com/develate/quasar-ext-components.git","type":"git","directory":"ae"},"description":"A Quasar App Extension","directories":{},"_nodeVersion":"22.22.2","dependencies":{"@clack/prompts":"^1.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.39","quasar":"^2.23.3","@quasar/app-vite":"^3.3.0"},"peerDependencies":{"@quasar/app-vite":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/quasar-app-extension-quasar-ext-components_0.0.2_1786225857432_0.1844865286423305","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@develate/quasar-app-extension-quasar-ext-components","version":"1.1.0","description":"A Quasar App Extension","keywords":["quasar","quasar-app-extension","quasar-app-vite","quasar-cli","vue","vuejs"],"homepage":"https://github.com/develate/quasar-ext-components#readme","bugs":{"url":"https://github.com/develate/quasar-ext-components/issues"},"license":"MIT","author":{"name":"Thorsten","email":"tk@programmierung.deutschehandarbeit.de"},"repository":{"type":"git","url":"git+https://github.com/develate/quasar-ext-components.git","directory":"ae"},"type":"module","main":"src/index.ts","imports":{"#q-app":"@quasar/app-vite"},"publishConfig":{"access":"public"},"dependencies":{"@clack/prompts":"^1.4.0"},"devDependencies":{"@quasar/app-vite":"catalog:","quasar":"catalog:","vue":"catalog:"},"peerDependencies":{"@quasar/app-vite":"^3.3.0"},"engines":{"node":">= 26 || ^24 || ^22.12"},"_id":"@develate/quasar-app-extension-quasar-ext-components@1.1.0","_nodeVersion":"14.18.1","_npmVersion":"9.6.4","dist":{"integrity":"sha512-ovL7aINZJlVI5FPhW+qizWIdLJPBFnnJ/dxS4F3YEK8wu4NHfMyINzYOVtlgIriJQrcDLsfD+e+mFpE23d7mkg==","shasum":"17735f52b34ebe65962760b2d7a3fd028fa6405e","tarball":"https://registry.npmjs.org/@develate/quasar-app-extension-quasar-ext-components/-/quasar-app-extension-quasar-ext-components-1.1.0.tgz","fileCount":23,"unpackedSize":214010,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDIGQ9dDB8mBJgEZdcaiWn69SHvrQdGkrPS/V54AVCtQgIgfEVfJOJJevOF8Cw1//XtpLdHUqYxVoaLchPcoa7Px6g="}]},"_npmUser":{"name":"thoasty","email":"thorsten@thoasty.de"},"directories":{},"maintainers":[{"name":"thoasty","email":"thorsten@thoasty.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/quasar-app-extension-quasar-ext-components_1.1.0_1787299350492_0.5248561296808196"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-05T18:56:43.460Z","modified":"2026-08-21T08:02:30.833Z","0.0.1":"2026-08-05T18:56:43.814Z","0.0.2":"2026-08-08T21:50:57.580Z","1.1.0":"2026-08-21T08:02:30.646Z"},"bugs":{"url":"https://github.com/develate/quasar-ext-components/issues"},"author":{"name":"Thorsten","email":"tk@programmierung.deutschehandarbeit.de"},"license":"MIT","homepage":"https://github.com/develate/quasar-ext-components#readme","keywords":["quasar","quasar-app-extension","quasar-app-vite","quasar-cli","vue","vuejs"],"repository":{"type":"git","url":"git+https://github.com/develate/quasar-ext-components.git","directory":"ae"},"description":"A Quasar App Extension","maintainers":[{"name":"thoasty","email":"thorsten@thoasty.de"}],"readme":"# @develate/quasar-ext-components\n\nThis package is a Quasar App Extension that copies app-owned Vue components into\nthe host project during installation. It currently provides:\n\n- **BottomSheet** - named snap points with optional per-step margins and corner\n  radii, inline or modal presentation, spring releases, scroll handoff, focus\n  management, and accessibility support.\n- **PopGesture** - interactive back-swipe navigation over a stack of panels.\n- **TabBar** - an iOS 26 \"Liquid Glass\" tab bar with FLIP morphs between item\n  sets, a liquid selection pill, scroll-driven minimize, a search morph, an\n  overflow tab, and a vertical rail on wide viewports.\n\n## Install\n\n```bash\nquasar ext add @develate/quasar-ext-components\n```\n\nThe extension copies these paths into the host app:\n\n```\nsrc/components/BottomSheet/\nsrc/components/PopGesture/\nsrc/components/TabBar/\nsrc/components/spring.ts\n```\n\n`spring.ts` is the shared sampled spring easing used by both BottomSheet and\nTabBar, which is why it sits beside the folders instead of inside one of them.\n\nImport components from the copied app files:\n\n```ts\nimport { BottomSheet } from \"@/components/BottomSheet\";\nimport { PopGesture } from \"@/components/PopGesture\";\nimport { TabBar } from \"@/components/TabBar\";\n```\n\nUninstalling removes all of the above and any edits made to those copied files:\n\n```bash\nquasar ext remove @develate/quasar-ext-components\n```\n\n## BottomSheet\n\n```vue\n<template>\n  <div class=\"relative-position\" style=\"height: 100dvh\">\n    <BottomSheet\n      v-model=\"open\"\n      v-model:step=\"step\"\n      :snap-points=\"snapPoints\"\n      dismissible\n    >\n      <template #default=\"{ step: activeStep }\">\n        <div class=\"q-pa-md\">Current step: {{ activeStep }}</div>\n      </template>\n\n      <template #full>\n        <div class=\"q-pa-md\">Content for the full detent.</div>\n      </template>\n    </BottomSheet>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from \"vue\";\n\nimport { BottomSheet } from \"@/components/BottomSheet\";\nimport type { BottomSheetSnapPoint } from \"@/components/BottomSheet\";\n\nconst open = ref(true);\nconst step = ref(\"peek\");\nconst snapPoints: readonly BottomSheetSnapPoint[] = [\n  { name: \"peek\", height: 96, margin: { x: 28, bottom: 24 }, radius: 28 },\n  { name: \"half\", height: \"50%\", margin: { x: 8, bottom: 10 }, radius: 20 },\n  { name: \"full\", height: \"92%\", radius: 16 }\n];\n</script>\n```\n\nInline mode requires a positioned parent with a definite height. Modal mode is\nenabled with `modal`; it teleports to `teleportTo`, renders a scrim, handles\nfocus and Escape, and can lock document scrolling. Snap heights can be pixel\nvalues, fractions between 0 and 1, percentages, `px` strings, or `\"content\"`.\n\nA step may also carry a `margin` (`x`, `left`, `right`, `bottom`, `top`) and a\n`radius`, given as pixels, `\"NNpx\"`, or a `\"NN%\"` of the container width for\nhorizontal lengths and its height for vertical ones. A step with a `bottom`\nmargin floats: it detaches from the container edge and rounds its bottom\ncorners, while a step without one stays flush and square. Both the insets and\nthe radii are interpolated between the two bracketing steps while the sheet\nmoves, so a step change morphs the shape rather than jumping it. `margin.top`\nonly caps how tall a step may resolve, behaving like a per-step\n`maxHeightFraction`.\n\nThe gap is produced by an inset clipping box (`[data-bs-frame]`) between the\nroot and the sheet, because a sheet that is translated down can never show its\nown bottom edge. That box clips, so the sheet's shadow does not spill into the\nmargin. When no step declares a margin or a radius, none of these writes\nhappen at all.\n\nResolved steps are sorted by position, bottom-most first, rather than by\nheight: with margins a short floating step can sit above a taller flush one, so\nthe step index, `getSnapHeights()` and `stepBy()` all follow the on-screen\norder.\n\nThe full API is documented in the copied `BottomSheet.vue` SFC and\n`types.ts`, including props, events, slots, accessibility options, the\n`--bs-*` CSS custom properties, and the exposed `open()`, `close()`,\n`snapTo()`, and `remeasure()` methods.\n\n## PopGesture\n\nPopGesture uses a stack supplied through `v-model` and exposes `push()` and\n`pop()` methods. Its parent must have a definite height, and the UI should\nalso provide a visible back control because the gesture is an enhancement.\nOnce the swipe owns the finger the dragged panel's scroller is frozen for the\nrest of the gesture, and `blurOnDrag` (on by default) drops the caret so the\nvirtual keyboard gets out of the way.\n\n## TabBar\n\n```vue\n<template>\n  <div class=\"relative-position\" style=\"height: 100dvh\">\n    <div id=\"feed\" class=\"fit scroll\"><!-- content --></div>\n\n    <TabBar\n      v-model=\"active\"\n      v-model:search=\"query\"\n      :items=\"items\"\n      minimize\n      scroll-target=\"#feed\"\n      aria-label=\"Main tabs\"\n    />\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from \"vue\";\n\nimport { TabBar } from \"@/components/TabBar\";\nimport type { TabBarItem } from \"@/components/TabBar\";\n\nconst active = ref(\"home\");\nconst query = ref(\"\");\n\nconst items: TabBarItem[] = [\n  { name: \"home\", label: \"Home\", icon: \"home\", badge: 3 },\n  { name: \"browse\", label: \"Browse\", icon: \"explore\" },\n  { name: \"search\", label: \"Search\", icon: \"search\", role: \"search\" },\n  { name: \"profile\", label: \"Profile\", icon: \"person\" }\n];\n</script>\n```\n\nThe bar is absolutely positioned and needs a positioned parent with a definite\nheight; `fixed` pins it to the viewport instead. `items` is watched by\nreference, so a morph requires a new array. An item with `role: 'search'`\nmorphs the bar into a search field, `minimize` collapses it while\n`scrollTarget` is scrolled down, `maxVisible` folds the tail into an overflow\ntab, and `orientation: 'auto'` becomes a vertical rail past `sidebarAt`.\nDo not nest the bar under an ancestor that establishes a backdrop root\n(`filter`, `opacity < 1`, `mask`, `contain: paint`) - it cancels the glass blur.\n\nSee the copied `types.ts` files for the complete public API and the SFC\nheaders for behavior and platform caveats.\n\n## Source and development\n\nThe extension source is organized as follows:\n\n- `src/templates/` contains the files copied into the host app.\n- `src/install.ts` invokes `api.render(\"./templates\")`.\n- `src/uninstall.ts` removes the copied component folders and `spring.ts`.\n- The repository's `playground/` is a local Quasar app for testing the extension.\n\nUse the repository root for development commands:\n\n```bash\npnpm install\npnpm run lint:check\npnpm run typecheck\npnpm run cycle\npnpm run dev\n```\n\nThe template files are the source of truth. Do not edit generated copies under\n`playground/src/components` directly. The npm package is named\n`@develate/quasar-app-extension-quasar-ext-components`; Quasar installs it\nusing the shorter extension id `@develate/quasar-ext-components`. To publish,\nupdate the package version and run `pnpm publish` from the `ae/` directory.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}