@bluerobotics/bluevue 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +113 -0
- package/dist/bluevue.js +1176 -0
- package/dist/components/BlueButtonGroup.vue.d.ts +101 -0
- package/dist/components/BlueExpansiblePanel.vue.d.ts +38 -0
- package/dist/components/BlueInput.vue.d.ts +70 -0
- package/dist/components/BlueLoadingDialog.vue.d.ts +27 -0
- package/dist/components/BlueMenu.vue.d.ts +57 -0
- package/dist/components/BluePromptDialog.vue.d.ts +37 -0
- package/dist/components/BlueSelect.vue.d.ts +76 -0
- package/dist/components/BlueSlider.vue.d.ts +51 -0
- package/dist/components/BlueSwitch.vue.d.ts +39 -0
- package/dist/composables/useBluePopover.d.ts +38 -0
- package/dist/index.d.ts +10 -0
- package/dist/style.css +2 -0
- package/package.json +64 -0
- package/src/assets/br-logo-white.svg +1 -0
- package/src/components/BlueButtonGroup.vue +382 -0
- package/src/components/BlueExpansiblePanel.vue +72 -0
- package/src/components/BlueInput.vue +247 -0
- package/src/components/BlueLoadingDialog.vue +76 -0
- package/src/components/BlueMenu.vue +119 -0
- package/src/components/BluePromptDialog.vue +151 -0
- package/src/components/BlueSelect.vue +236 -0
- package/src/components/BlueSlider.vue +464 -0
- package/src/components/BlueSwitch.vue +117 -0
- package/src/composables/useBluePopover.ts +153 -0
- package/src/index.ts +11 -0
- package/src/styles/bluevue.css +124 -0
- package/src/styles/bundled.css +9 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400"><g fill="#fff" fill-rule="evenodd"><path d="M185.5.4c0 .2-1 .3-2 .2a7 7 0 0 0-2.4.1q-.3.4-1.3.2c-.5 0-1.3 0-1.6.4q-.7.5-.3 0 .1-.5-.1-.5-.5 0-.5.4-.1.3-1.4.2-1.5-.3-2.5.5l-1 .8 1 .3q1.4.2.2.6-1 .3.1.3.8 0 1.1.5t-.2.1q-.5-.1.1.3t.7 1q0 .3 1.5 1.6 1.3 1.2.9 1-.6-.3 0 .5.3.8.7.9t.4.6.8.5.7.3c-.1.6.5 1.7.9 1.5q.3-.1.3.2.1.4.7 1.1.7.6.1.3-.4-.2 1 1.1t1 1.2q-.5-.3-.3.1t1 .5q.5 0 .3.2c-.3.4.9 2.5 1.5 2.5q.5 0 1.2.9l.8.9-1-.8q-1-.9-.7-.2.2.6 1 1l1.4 1q.4.4-.3 0-1-1-.3.2.5.9 1 1t1.2.8.2.4q-.7-.6-.6.1 0 .8 1 .6.4 0 .3.5 0 .4.4.5l.7.1-.2.6q-.7.9.9.7.3 0 0 .3 0 .3.3.4.6 0 0 .3t.4.8q1 .6.5 0t.3 0q.6.5.5.9t.7 1.3.6 1 .6.7q.9.7 1 1.3t.5 1q.4.2.1-.3-.2-.5.1-.2.5.3.5.8t.9 1.2q.7.5.3.4-.4-.2.5.7 1.1 1 1.3 1.7t1 1.5.8 1.3q0 .4.6 1 .9.6.3.6t.3.5q.7.5.8 1c0 1 .2 1.2 1 1.5q.6.2.5.5-.2.4.4.7.6.4.6.6c0 1 .9 2.7 1.2 2.2q.3-.6.4 0c.1 1.5 1 3.1 1.9 3.6q.8.4.6 1-.1.5.5 1.2.7.5.6 1.1-.1.5.7 1.1.7.5.6 1.2-.2.5.6.8 1 .1.3.8t.2.6q.5 0 .4.4-.2.3.1.4c.3 0 1 2.1 1 2.8q-.1.3.5.3t.4.3.4.6.1.9.3.5.2.4q-.7.2.3 1 1 .6.4.6t.3.7c.5.3 1 1.2 1 1.8.2 1.5.9 3.2 1.4 3.5q.5.3 0 1-.8.7.2.3.7-.3.4.5-.1.7.2.8.3 0 .4.7 0 .8.5 1.2.6.6 0 .3t-.5 0q0 .4.6.7t.4 1c-.2 1 .1 2 .6 1.7q.2 0 0 .6 0 .8.3.8t.2.6.2.6.2.6.4.6 1.2.6.6.1.6 0 1.1.3q.6-.1.6.1.1.3.8.2t.8.2.6.2q.6-.2.6.4 0 .5.6.6c.8 0 .8 0 2 .6q1 .5 1.4.2.5-.3 1.2 0 1.2.5 0 .2h-1c0 .5 1.8.8 2.1.4q.3-.5.3.3t.9.6q2-.2 1.6.4c-.3.5 1.7 1.3 2.6 1q.8-.2.5.3-.2.7.6.5.7-.1 1 .4.3.7 1 .4.8 0 .5.2-.1.4.3.3t1.2.5q.6.7 1.4.8.9 0 1 .4 0 .2.5.4t.3-.2c-.3-.6 1.1.5 1.6 1.2q.3.3.8.2t.8.3q.3.5-.1.2t-.5 0 .8.7q.7 0 .6-.2-.2-.3.4-.1.5.3.4.5c-.2.3.5.8 1 .7q.4 0 .8.6t1.1.7q.7 0 .8.4 0 .3.6.4.5 0 1 .8.4.7.7.5t.4.2.4.2q.4 0 .6.3.3.4-.1.2t-.5 0c0 .5 1.5 1.1 2 1q.4 0 .2.2c-.2.3.6 1 1.4 1l.6.4q.2.4-.2 0-.5 0-.5.2 0 .4.6.4t.8.6.9.8.2-.3q-.2-.4.4.2.5.7.6.4l.7 1c.5 1.1 1.8 2 2.6 1.7q.3 0 .1.2a39 39 0 0 0 8 7.7c-.2.7.4 1.8.8 1.6q.3-.2 0 .4-.2.9.5.4.8-.3.3.3-.7.8 1.2 1.2c.3 0 .9.6.9 1q.1.4 1.1 1.4 1.1.9.5.6-.7-.6-.6 0 0 .4 1 .8.9.3 1 .6h-.5q-.3-.2-.4.1.1.3 1.1 1 1 .4 1 1t1 1.9 1 1.4q-.2.2.4.4.5.3.4.6-.2.4.4.6.5.2.4.6t.3.6q.6.3.6.7.3 1.7 1.1 1.8.6 0 .4.6t.4 1q.6.2.3.3t.6 1q1 1 .5.8t-.3.4q.4.5.7.6.4 0-.1.4-.7.4 0 .3.7 0 .7.3c-.2.5 1 2.9 1.3 2.9q.3 0 .3.3-.2 1.3.4 1 .4 0 .4.2t-.4.4q-.4.1.5.8t.4.8q-.6 0 0 .8.4.6.8.5.3-.2.2.4-.2.5 0 .6.4 0 .2.7t.1.4c.5-.3 1 .9.8 2.3q-.2.9.3 1t.8.6q.4.8-.5 0-.4-.3.3.6c.8 1 .9 1.2.4 1.5q-.7.4.2.4.7 0 .4.6-.1.6.4 1.4t.3 1.4.2.3.3.6.3 1.2 0 .3-.3.6q.2.8.6.1.4-.4.1.7t.2.8.2.8.2.7.3.6.2 1.7q.5.9 0 1-.3.1-.2.7.2.8.6 0 .4-.4.1.7-.1 1 .2 1.6.5.5.2.6t.3.6q.6.8 0 .4t-.3.2.3 1.6.3.9.4.2-.5.4q-.6 0 0 .3.4.4.3 1.1l.1 1q.3 0 .3 1.8l.1 2.2q.6 1.2 0 2.1-.6.7 0 .3.6-.5-.1 3.2-.1.9.2.6c.5-.2.3 4.5-.2 6.4l.1.9c.5 0 .5 1.7 0 2q-.5.3 0 .3c.3 0 .4 1.1 0 1.8q-.2.5-.1 2.2 0 2-.6 1.9-.5 0-.2.3c.4.3.7 2.8.2 2.7q-.6-.1-.2 1 .2.7-.3 1.3-.6.9.1.4t.1.1q-.3.6-.2 1 0 .6-.2.6-.4.1-.6.8t.2.5 0 .6l-.5 1.6q0 .7-.4.8-.4 0 0 .6.6.5-.2 1.2-.6.8-.2.9t.4.5-.4.1-.1.8-.3.8-.2.3v.7q-.4 0-.2 1 .2 1.2-.3.7-.6-.3-.3.3.1.8-.5 2-.6 1.3-.3 1.2.5-.2 0 .3l-.4 1q0 .6-.5 1-.4.2-.2.6.1.5-.2.5t-.2.5-.1.6q-.4 0-.6.7l-.3 1.3q.4-.6.4-.1t-.7.9-.6.8-.3.3 0 .4q.8.4.1.4-.4 0-.3.6t-.1.6q-.4 0-.2.4.1.3-.3.8t-.4 1.1v.3c-.5-.3-1.6 1.2-1.3 1.7q.2.3-.1.4-.5 0-.2.4 0 .3-.2.4-.4 0-.3.3.2.4-.3.6t-.6.6.5.2q.4-.1-.2.3-.6.6-.7 1.3 0 .5-.4.4-.6-.2-.4 1 0 .5-.6 1.2-.6.9-.6.3 0-.4-.4.4c-.5 1-.6 1.4-.7 2.3q0 .5-.3.3c-.3-.3-1.4.8-1.1 1.3q.2.3-.4.6-.5.1-.4.6.3.3-.4.4-.5 0-.5.5.2.4-.4 1-.8.8 0 .3.4-.3-.5.6-1 1-.8 1.2.1.3-.3.3-.3 0-.2.3 0 .4-.5.9-.8.8-.3 0t-.3 0q-.8.4-.2.8.6.3-.1.3c-.6 0-1.3 1-1.2 1.7q0 .2-.5.3a1 1 0 0 0-.8.4q-.3.5.2.2t-.3.5q-.7.6-.6 1 .1.2-.3.2c-.8 0-2.8 2.3-2.5 2.8q0 .3-.9.9c-1 .5-5.7 5-5.3 5l-.3.7q-.4.7-1 .5-.4 0-.7.6-.4.8-.7.7-.4 0-1 1-.4.8-.5.6t-.8.6-.5.4-.4-.3q-.5.3-.3.9t-.3.3c-.4-.3-1.6.6-1.6 1.3q0 .3-.5.2a1 1 0 0 0-.9.3q-.3.4.3.1t0 .3-.9.5-.3.2-.3.3-1.2.8q-.8 1-.6.4.5-.7-.3 0-.5.6-1.2.8-.6.1-1.3 1-.6.7-.8.7c-.4-.2-1.3.4-1.1.7s-1.2 1-2.6 1.1q-.3 0-.2.4c.3.5-1 1-2.5 1.2q-.3 0-.2.5.2.5-.3.2-.7-.3-1 .5-.5.7-1 .5-.7-.2-.7.3 0 .3-.3.2-.4-.2-.4.2 0 .3-.4.2-.3-.2-.4.2 0 .4-.4.1-.3 0-.4.2 0 .4-.3.4-1.3-.2-1 .5.1.3-.3.2-.6-.1-1 .4-.6.4-1 .3-.2-.1-.3.2t-.6.1q-.5 0-.6.3t-.3.2c-.4-.2-.4 3.3 0 3.9q.2.5 0 1.6 0 1.3.4 1.3.3 0 .1 1.2t.2 1.2.2 1 .2 1 .1.5q0 .6.3 1.2.5.6 0 .6-.3 0 .3 1l.6 1.2v.4l-.1 1q0 .7.3.5.6-.3.2.7-.2 1 .3 1t0 .4q-.7.4 0 .4c.8 0 1 1 .2 1.3q-.3.2.2.2.7 0 .5.7t.1.4.2.6.4.5 0 .3q-.8 1 .4.7.7.2-.2 1.1-.6.7.3.3t.2.3q-.6.9.4.7.3 0 .1.7t.2.8q.2 0 .4.9 0 .7.4 1 .3.1.2.7-.3.6.2.4.3-.2.4 0 0 .5-.4.6-.2.1.4 1 .9.8.3 1.2-.5.4.2.4c.7 0 1.3 1.2.6 1.2q-.4 0 .2.5.8.6.2 1-.6.6.3.2.7-.3.5.2c-.4.6 0 1.7.6 1.4q.4-.2 0 .2 0 .5.3.9.7.3 0 .3-.8 0 0 .5c.7.5.8.7.8 1.7q0 .5.4.3t.2.1c-.3.6.1 1.8.6 1.5.3-.2.5.6.4 1.5q0 .2.3.3t.2.5.4.8.4.8q0 .5.2.6t.4.8q0 .7.4.8.3 0 .2.4-.2.3.1.3t.2.6.3 1q.5.6.5 1.2c0 .7.7 1.5 1 1.3s.8 1 .6 1.4q-.2.3.2.4.3 0 .2.4-.2.4.1.4.5.1 1.3 1.6.6 1.5.4 1.3-.5-.2-.2.4.3.5.5.4.3-.2.6.4.1.5-.2.4-.4-.2-.1.3.2.6.6.7t0 .3q-.9.5 0 .4.6 0 .5.4t.5 1.1q.8.9.6 1-.2.3.2.3t.3.3.6 1q.6.8.5 1.4-.2.8.6 1.2.6.5.5 1t.1.4q.5 0 1 .6.5.8 0 .5c-.7-.4.2 1.3 1.3 2.5q.6.7.4.8-.2 0 .4.6.8.6.3.4c-.7-.4-.6.4.3 1.5.8 1 2 1.5 1.4.7q-.1-.3.7-.2.9 0 1.4-.6.6-.6 1-.5.6 0 .6-.3t.4-.2.4-.1q0-.4.6-.6t.3.1q0 .3 1.2-.2t1.1-1q0-.3.2-.4.4.1.6.5t.2-.3q0-.9.4-.1.4.7 1.1-.2 1-1.2 0-.2-1.1.8-.3-.1.5-.6.9-.5c.4.3 2.7-1 2.7-1.4q0-.3.3-.2.4.1.4-.1 0-.5.6-.2.6 0 1.7-.9 1.3-1 1.3-.5t.3-.3 1.4-.7.8-.4q-.2-.6.5-.3.6.1.3-.2-.2-.8 1.9-1 .7-.2 1.3-.9.5-.7 1-.8c1 0 1.8-.6 1.6-1q-.2-.4.4-.2t.9-.3q.1-.5.5-.4.3.2.5-.4.4-.6 1-.5.9.3 1-.5.3-.7.5-.6c.3.4 1.7-.5 1.5-1q-.2-.2.3 0 .7 0 1.2-.8.8-1 1.2-.8.6 0 1.1-.7.7-.9.7-.3 0 .5.5-.4c.5-1 2.5-2.5 2-1.6q-.1.4.8-.6t1.4-1 .4-.4.3-.2q.4.3.4-.4t.6-.4 1-.6q.3-.8.4-.5 0 .3.6-.5.6-1 1.2-.5t.3-.1.4-.7q.5 0 .6-.6t.4-.4q.5.2 1.7-1l1.7-1.4q.3-.2.2-.6t.5.1q.7.8.5 0 0-.5.5-.4t.3-.2.7-1 1-1.3q0-.5.2-.5.4 0 1.5-1 1.3-1.4.4-.3-.4.7 2-1.7c1.4-1.5 2.8-2.7 3-2.7l.4-.6c.3-.8 3.5-4 4.1-4q.4 0 .4-.2a16 16 0 0 1 2.6-3q2.4-2.4 1.7-2-1 .8.2-.4 1.2-1 1.1-1.5 0-.2.5-.3c.7 0 3-2.9 2.6-3.3q-.1-.2.1-.1.4 0 .5-.2l1.5-1.6q1.3-1.4 1.1-1.8-.1-.3.4-.4.6 0 .6-.6t.7-.4.4 0q-.2-.4.2-.9.6-.7-.1-.3-.4.2.2-.3t.4-.6q-.3 0 .5-.4t.6-1 .4-.6q.7 0 .4-.4 0-.3.2-.4.4 0 .3-.3.1-.5 1.1-1.4 1-1 .6-.8-.5.3.2-.7.6-.8 1.2-1.2.6-.2.4-.5t.6-.8.6-1.1.8-1.2.7-1.2q-.1-.5.2-.3.3 0 .8-.6.3-.7 0-.8-.2 0 .4-.4t.7-1.2q0-.7 1-1.6.6-.9.7-1.4-.1-.4.2-.3c.4.2 1-.7 1-1.6q.1-.5.8-1t.8-1.3c.1-1.1.7-2.1 1-2 .4.3 1.3-1.6 1-2q-.2-.5.5-.8.5-.4.3-.4-.2-.1.7-1.3 1-1.1.9-1.7-.2-.5.2-.6.3 0 .1-.4-.1-.3.2-.3.4-.2 1.2-1.6.8-1.6.3-1.3-.4.1.2-.5l.4-1q-.2-.3.2-.3.3 0 .2-.7-.2-.6.1-.4.4 0 1-1.1.6-1.3.3-1.2t-.1-.3.6-.6q.3 0 .1-.4-.1-.3.2-.4.5 0 .2-.6l.1-.6q.4-.1 1-1.4t.3-1.2q-.3.3-.2-.5.3-.7.7-.5t.1-.4q-.2-.7.4-1.2.5-.6.4-1-.2-.4.3-.8t.4-1.3.2-.5q.6.4.3-.3t.1-.6q.4-.1.4-1t.4-1 .2-.6.2-.6q.5 0 .2-.8 0-.6.3-.5.3.3.1-.6 0-.7.2-.6.5.3.2-.5-.1-.9.2-.6.4.2.1-.7t.2-.6.4-.2c-.2-1.1.5-3.9.9-3.6q.4.3.2-.4-.2-.5 0-.6.4-.1.3-.8t.2-.8.2-.6.2-.8q.2-.1.2-1-.1-.8.2-.5.5.3.2-.8t.2-.8.2-.8.2-.7.2-.8.2-.8q.4.3.2-.2t.1-1 .2-1.2q0-.7.2-1c.3 0 .5-1 .5-1.8q0-1.6.4-1.7.2 0 0-1 0-.9.3-1 .4 0 .3-1.3 0-1.2.2-1.6.2-.2 0-.8-.1-.5.2-.5.4-.1.4-1.3.1-3.7.5-4 .3-.3 0-1.2 0-1 .3-1.5.5-.5.3-2-.1-1.2.2-1.3.3 0 .3-.4t-.5-.2 0-.2.2-1.8q0-1.3.3-1.3t.2-2.4q0-2.1.2-2.3c.1 0 .3-6.2.3-13.7a170 170 0 0 0-1.2-21.5q-.5-.6 0-.2.5.1.5-.2t-.4-.4q-.3 0-.1-1.6.3-1.5-.2-1.4-.3.3-.3-1.3.1-1.4-.2-1.7-.2-.3-.2-1.4.1-1-.2-1.4-.3-.2 0-1.3 0-1.2-.3-1.2-.4 0-.3-.5t-.3-1q-.5-.7.1-.3t.3-.6l-.4-1.4q0-.5-.3-.5t-.1-1q0-1-.3-.7-.4.3-.2-.7t0-1.3-.2-1-.2-1q-.3-.1-.2-1 .1-.7-.2-.7t-.2-.9q.3-.8-.3-.5t-.2-.7q.3-1.2-.2-.8t-.2-.8q.3-1-.1-.8-.5.3-.2-.8t-.2-.8c-.4.3-.6-1-.5-2.4q0-.5-.2-.5t-.4-1.2q0-1.2-.5-1.5t-.5-1.5-.3-1.3-.1-.6-.3-.3-.2-.2c.3-.5-.1-2.4-.6-2.2q-.2 0 0-.6 0-.9-.2-.6-.5.2-.2-.6.1-.8-.2-.6t-.3-.5q.2-.8-.2-.8t-.3-.3q.1-.1-.2-.7a4 4 0 0 1-.6-1.8q-.1-1-.7-1.8-.5-.6-.4-1.1t-.2-.3q-.5.3-.2-.4 0-.5-.2-.6t-.2-.6q.1-.6-.1-.4-.3 0-.6-.6 0-.7.2-.6.9.6-.4-1-.7-.7-.6-1.3.2-.5-.4-.7-.6-.3-.6-.8c.2-1 0-1.9-.4-1.6q-.3.1-.2-.4.3-.5-.4-.8-.6-.2-.4-.8.1-.5-.1-.6c-.3 0-.8-1-1-2.1s-.7-2.2-1-2q-.4.3-.1-.4.2-.7-.3-.4t-.3 0c.3-.5-1.3-4.1-2.2-4.8q-.5-.5-.4-.8t-.5-.6-.4-.8-1-2q-1-1.2-1-1.6.2-1.2-.7-1.3-.6 0-.4-.6t-.4-.9-.9-2q0-.4-.6-.4t-.3-.4q.2-.5-.4-1l-.7-.7q-.3-1.6-.8-1.1-.5.2-.2-.4.1-.6-.2-.6-.5 0-.5-.6t-.3-.4q-.2 0-.3-.6 0-.8-.4-.6-.4 0-.4-.6t-.5-.7q-.4 0-.5-.6c0-.4-.6-1.4-1.3-2.1a7 7 0 0 1-1.5-2q0-.7-.6-1-.6-.5-.5-.7 0-.3-1.2-1.7l-1.3-1.7q0-.2-.7-.5t-.3-.3-.4-.7-.2-.3q.5.1-.7-1-1.3-1.1-.9-1 .6.3.3-.1t-.9-.5-.3-.3c.3-.5-1-2-1.6-2q-.5 0-.4-.4.2-.2-.4-.5-.5-.3-.4-.7 0-.5-.8-1t-.7-.6q.2-.4-.6-.7-.7-.5-.6-.7c.3-.3-1.4-2-2-2l-.7-.5q-.3-.4.2-.1.3 0-1.9-2t-2.2-2.5c.2-.4-1.6-2-1.9-1.8 0 .2-1.2-.9-2.4-2.2q-2-2.2-2-2 .3.6-.1.3l-.5-.7q0-.6-1-1.4t-1-.6-.5-.5-1-.7-.4-.3-.6-1.1q-1-.8-.2.2.4.7-.7-.6t-1.6-1.2q-.4 0-.2-.3.1-.4-.7-.8l-1.4-1.1q-.5-.7-.2 0 .1.4-1-.9-1.1-1.1-1-.7l-1.3-1.1q-1.6-1.6-2.1-1.4-.5.1-.2 0c.4-.5-2.4-2.6-3.3-2.6q-.7-.1-1.2-.8t-1.7-1.6q-1.3-1-.5-.2.9 1.2-.5 0-1-.7-.8-1 0-.3-.5-.3t-.6-.4q0-.4-.3-.2-.4.1-.6-.4-.3-.5-1-.6-.8 0-.6-.4t-.2-.2-1.6-1q-1-1-1.5-1-1.2 0-1-.5t-.2-.4l-.8-.2-.8-.1q-.3-.1-.2-.5.2-.3-.1-.4l-.8-.2-.8-.1q-.5 0-.2-.4 0-.3-.8-.8-1-.5-.8 0 .3.3-.5 0-.7-.6-.6-.9.1-.5-1.1-.3-.3 0-.3-.3 0-.4-.6-.6-.6-.3-.4.2t-.9-.6q-1.1-1-1.7-.8-.4.2-.2-.1c.2-.4-2-1.6-2.6-1.4q-.2 0-.3-.3 0-.4-.3-.2-.4.1-.4-.2t-.3-.3q-.2.2-.8-.3t-1.2-.4-.2-.2-.4-.2q-.6 0-.7-.2t-.3-.2q-.4.3-.4-.1-.1-.4-1-.4t-1.2-.6-.6-.4q-.3.1-.4-.2 0-.4-.4-.3-.6 0-1.6-.6t-1.5-.5q-.5.4-.2-.2.4-.5-.5-.2t-1.1-.3c-.5-.7-4.3-2.2-5-2q-.7.3-.5-.1.2-.3-.3-.7-.6-.2-.3.3.1.4-.5-.2-.8-.7-1.5-.4-.9.3-.4-.3.3-.5-.6-.3t-.5-.2q.2-.3-.4-.1-.6 0-.7-.2t-.6-.1-.5-.2-.6-.2-.6-.2-.6-.2q-.5.1-.6-.2t-.6-.2-.6-.2q0-.5-.8-.2t-.6-.2q.4-.6-1.6-.5-.5 0-.5-.3t-1 0q-1.2.1-.7-.4.3-.5-.4-.3-.5.3-.6-.1-.1-.3-1-.1-1.2.3-.8-.3t-.5-.2-.8-.2q0-.3-.6-.2t-.8-.2-.8-.2-.6-.2-.8-.2q-.6 0-.7-.2t-1-.2q-1 .3-1-.2 0-.3-1-.2-1 .2-1-.1 0-.5-.7-.2-.8.1-.8-.2t-.7-.4c-2.9-.1-3.5-.2-3.3-.5q0-.3-.7 0-.8 0-1.1-.2c-.4-.6-2.9-1-2.5-.4q.3.6-.4 0t-1.4-.3-.8-.1-1-.2q-.8.1-1.2-.2c0-.2-.7-.3-1.2-.2q-1 .2-1.6-.3-.5-.3-1.9-.2-1.2.3-1.3-.1 0-.4-.5-.4-.3 0 0 .5.1.5-.3 0-.6-.4-1.7-.3-1 0-1.3-.2c0-.2-1.1-.3-2.3-.2q-2 0-2.3-.2c-.3-.4-28.8-.4-28.8 0M114 19.1q-.7.1-.7.5t-.4.1q-.4-.1-.4.2 0 .5-.4.2-.4-.1-.4.2t-.4.2q-.3-.1-.4.2 0 .3-.4.2-.3-.1-.3.2t-.4.2-.4.2-.4.2-.4.2-.3.3c-.3-.4-2.4.8-2.4 1.3q0 .4-.3.2t-1.2.6-.7.4q.3-.6-.7 0-1 .4-.8.8t-.2.1q-.4-.2-.9.3l-1.1.6q-.6.1-1 .8l-1 .7c-1 0-1.9.6-1.7 1q.1.1-.4.4t-.4-.2q.3-.4-.4.3-.5.6-.6.4t-.6.4-.5.4-.8.6q-.8.7-1.2.5t-.6.4-.8.4-.5.4-.4.4-.7.3q-.1.6-.7.4t-.6.5q0 .6-.2.4-.3 0-1 .7t-1.2.8c-.9 0-3 1.5-3.3 2.3q-.4.8-.8.8-.5-.1-.5.3t-.4.1q-.4-.1-.3.1 0 .3-.2.3l-.9.8q-.5.6-.3.2t-1 .4q-1 1-1.2 1.4 0 .4-.7.4t-1 .8q-.6.8-.8.7c-.3-.4-1.8 1-1.8 1.7q0 .4-.4.3-.3-.2-.5.4-.4.5-.7.5-.5 0-1 .8t-.5.6-.8.5q-.7.9-1 .8t-1.3 1.2q-.7 1.2-.8 1c0-.2-.8.5-1.6 1.4q-1.5 1.6-1.4 1.2.3-.6-.5.1l-.7 1q0 .5-1.8 2.2l-2 2 1.9-2.1c1-1.1 1.8-2 1.5-2-.2 0-1.4 1.2-2.7 2.6q-2 2.3-1.7 2.2t-1 1.2c-.9.8-1.5 1.7-1.5 1.9q.1.2-.3 0-.3 0-.4.2 0 .3-.5.4-.6 0-.6.4t.4.2.2.2q-.3.3-.6.2-.4-.1-1.2 1-.8 1-.5 1.2.3 0-.7.5-.8.5-.8 1 0 .3-.5.7-.6.1-.4.5.1.3-.3.4-.7 0-1.1.7-.7.8 0 .3t0 .2q-.6.7-.5.9.2.2-.4.2c-.7 0-1.6 1.3-1.2 1.7q.2.3-.3.3c-.5 0-1.7 1.4-1.7 2q-.1.5-.8.7-.8.3-.2.4.7 0-.2.7-.7.7-.8 1-.1.5-.8.8c-.8.4-2 2.3-2.1 3.2 0 .6-1.2 1.7-1.9 1.7q-.7-.1 0 .4t-.2.4q-.7 0-.5.6.3.6-.1.4t-.4.2q.1.9-.9 1.5a3 3 0 0 0-.9 1.6q0 .9-.6 1.3-.4.5-.1-.3.4-1-.2-.1-.4.7-.3 1 .3.4-.4.6-.5.3-.4.5.3.2-.4.8-.6.5-.2.3.5-.2.2.4-.1.5-.5.4c-.3-.2-1 1-.8 1.6q0 .4-1 1.1-.8.7-.8 1.2.2.5-.4.7-.5.3-.4.9.2.5 0 .4-.4-.1-.8.8-.6 1 0 .7.3-.2-.5.7l-.7 1q.3.1-.7 1.1-.8 1-.8 1.5.2.5-.4.8-.6.2-.3 1 .2.7-.3.7t-.4.5-.3.5c-.4-.2-.8 1-.6 1.4q.2.4-.1.4-.5 0-.5.6t-.4.6 0 .3q.8.5-.1.4t-.2.4q.6.4 0 .4-.4.1-.4 1t-.4.8q-.5-.5-.6 1 0 .5-.7 1.2-.6.8-.7 1.2 0 .5.4-.1t.4-.1-.8.9-.5.8q0 .3-.2.3-.3.1-.3 1t-.2 1q-.3 0-.1.4 0 .4-.3.4t-.2.6-.4 1.1-.5 1.1q.2 1.5-.4 1.3-.3-.2-.1.4 0 .5-.3.6-.5 0-.3.7.2.8-.2.6-.3-.2-.2.4.3.5-.1.6-.3 0-.2.4.3.4-.4 1.3t-.2.5-.1.5-.2.6-.2.5-.5 1.5q.1.5-.1.6t-.2.5q.2.6-.2.6t-.3.8-.2.5-.2.4 0 .7q-.5 0-.3.8 0 .7-.3.7-.5 0-.5 1.4T7 147t-.1.5q.1.6-.2.9t-.2.8-.2.5-.1.6-.2.8-.2.6q.1.3-.2 1-.5.6-.3 1v.9q-.5.1-.6 1-.1.7.1.5.8-.4-.2 1.5c-.7 1.4-1.4 4.7-1.1 5.7q.2.8-.3 1.5l-.2.5q.3.1-.1.5-.4.6-.3 1.3c0 .4-.1 1.4-.4 2q-.4 1.2-.1 1.1.3-.2.3.4 0 .5-.3.7-.3.4-.2 1.8.1 1.6-.4 1.5c-.4 0-.5 0 0 1.8q.2 1-.2 1t-.4.5.5 0 0 .4-.4 1.6q.1 1-.2 1.3c-.2.1-.2 1.2-.1 2.3q0 2-.2 2.1a300 300 0 0 0 0 29.6q-.7.7-.1.4t.5.3-.4.4q-.6-.3-.1.5.3.8.2 1.2-.1.6.3 1.1t.1.4-.4.3.4.3.1.5q-.1.7.3 1.3.5.8 0 .3-.5-.1-.5.1 0 .5.4.5t.1 1.3q-.1 1.3.2 2 .5.5.3 1.4 0 .9.3 1.6.5.7-.1 1t.2.8.2 1q-.5.9.3 1.3l.2.3q-.4 0-.4 1.2 0 1.3.6 1.3t.2 1q0 1 .1.9c.3-.2.4.4.5 3.3q0 .6.4.7t.2.8.2.8q.3 0 .1 1t.2 1 .5.3-.4.2q-.3 0-.1.6t.6.8q.5 0 0 .4c-.6.6-.2 1.6.4 1.2q.4-.2 0 .4-.7.6 0 .8t.4.9q-.1.5.2.6.5 0 .2.8t.2.6c.6-.4.5.6 0 1.2q-.6.5.1.5t.4.6q-.2.7.3.4.6-.5.3.7l.1 1q.3 0 .3.5 0 2 .5 1.7c.5-.4.5.3 0 .9q-.7.4.1.4t.5.6q-.1.5.2.6t.2.6.3.7-.1.8q-.8.8.2.4.7-.3.4.3-.1.7.3.9t0 .2q-.6 0-.2.7.3.8.1 1-.2.4.4.1.8-.3.5.7-.2 1 .4 1.2.9.1.1.9-.7.8.2.4.6-.3.7.1 0 .3-.4.4-.2.1.4 1.3l1 2.4c.1 1.2.9 2.5 1.4 2.5q.3 0 .1.4-.2.6.5 1.5t.6 1.6q0 .4.3.4t.2.4.4.6.6 1.2.4 1 .1.4q0 .3.2.3t.2.7q-.3.6.2.4.3-.3.2.2-.2.6.4 1.2.5.6.3.8-.1.3.3.3.3 0 .2.3t.2.5.5 1.2q0 1 .4 1 .3.1 0 .5t.4.2.4.2q0 .5.9 1.6t.6 1q-.5-.2-.5 0 .1.5.5.7.5.3.6 1 0 .9.7 1.4.5.4.2 0l-.4-.8c0-.5 1 1 1 1.5l.1 1q0 .3.4.2.4-.2.6.4t-.2.3 0 .6.8.6.5.3v1.1q.1.5.6.5.6-.1.4.4-.2.7 1.1 2t1.1 1.9q-.3.4.2.1t.4.6.6 1q.5.2.4.6c-.3.4.5 1.6 1 1.3l1 1q.8 1 0 .5-.6-.6-.8-.1-.2.3 0 .4c.8 0 3.4 2.6 3.2 3.2q-.1.5.3.8.5.2.6.6c0 .6 1.4 2 1.8 1.7q.1-.2 0 .2t.7 1.4q.8.9.7 1.2t.4.2q.5 0 .9.4.2.4-.5.2-.5-.2.8.8c1.4 1 2 1.7 1 1.2q-.4-.2.2.3t.3.7.8 1.1a3 3 0 0 0 1.6 1q.4-.3.2 0t.8 1.3q.8.8.3.4-1-.8-.3.3.6.8 1.1.6.6-.1.4.2-.2.5.4 1t.8.9q0 .3.4.4.3 0 .7.3.3.4-.1.1-1-.5 0 .7.4.4.9.4.4-.1.7.3.4.4-.2.1-.3-.1.2.8t1 .8s.9.6 1.7 1.5q1.5 1.5.4.6-1-1 .6 1 1.7 1.9 2 1.6.5-.5.4.7 0 .2.5.2t.3.4.3.3c.5-.3 1.7 1.2 1.4 1.8q-.3.5 0 .2.4-.2 1.1.4t.5.1q-.4-.6.1-.2t.3.8c-.2.5.5 1.3 1 1.3q.3 0 0-.5 0-.3.2-.1.3.3.3.8.1.4.5.4.6.1 1.1 1t.6.4.3.4 1 1 1 .7q0 .8.4.2t.4 0c0 .9 1.8 2.5 2 1.9q.3-.4.3.2t.4.5.6.2q.3.5-.1.2t-.5 0 1.2 1 1 .2l.3.2q.5.7.9.4.2-.2 0 .4-.1.6.2.7 1-.2 1.2.6.3.5.8.3.3-.1.2.1-.1.4.7 1.3.9.7 1 .4t1 .7q.8.9.9.5.1-.3 1.6 1 1.4 1.6 2.2 1.6.7 0 .6.4t.7.5.6.3q-.1.2 1 .7t1.2.9.5.2q.5-.2.5.5t.7.7 1.2.6q.4.4.9.3.3-.2.4.3 0 .5.3.6 1.7.1 2.1 1 .4.5.9.3.5-.1.7.7.3.9 1 .5.8-.3 1.5.8.6.9 1 1t1.2.6.7.3-.5-.7q-.5-.1 0-.2.4 0 1 1t1.4.8.7.3q0 .3.8.4.8 0 .6.6t.2.2q.6-.1 1 .2.7.4 1 .2.6-.3.2.2t.3.3.4.4.8.4 1.4.5 1.2.5.8.2.6.2.8.3-.2.2-.4.1 1 .3h.8c-.3.3 1 1.3 1.7 1.3q.8.1 0-.4-.6-.4 0-.4.3 0 .7.6.2.6.6.5 1.6-.1 1.3.4c-.3.5 1 1.2 2 1.2q.9.1-.2-.4-1.8-.9.3-.3 1 .4 1.2.8 0 .3.6 0t.4.3q-.2.3.3.2.5-.2 1.1.4.8.6 1.8.7a4 4 0 0 1 1.8.6q.5.4.7.2.3-.1.3.3t.8.2.5.3.6.2q.8-.2.6 0c-.1.3 1 1 1.9 1l.5.3q.4.2.9-.2.7-.6.3 0t.3.4h.6q.1.3 1.3.4 1 .1 1.5.5.3.5 1.5.5t1.2.4.5.2c1.4-.1 2.7.1 2.4.5q-.3.5.8.2 1-.2.8.1-.3.5.8.2t.8.2.8.2.7.2.5.3 1 .4q.3.5.9.5t.3-.5q-.2-.4.4 0 .6.6 1.2.4t.8.4.7.2c.5-.6 1.6-.7 1.3-.1q-.2.3.8.2 1-.3.7.2t.3.3q.5-.2 1 0c.5.6 3 1 2.6.5q-.1-.4.2-.4t.4.4q0 .4 1.1.2t1.4.1.6.3.6.2.6 0q.3-.8 1.1.1t1.3.3c.8-.6 1.9-.4 1.6.3q-.3.6.5.3 2.4-.9 2.5-.3 0 .4.4.4t.2-.5q-.4-.5.2 0t1.6.3q.8 0 1.4.3c.2.1 1.4.2 2.6.1a272 272 0 0 0 30.5.1q.6.5.8.2t1-.2q2 .6-1.3-2.4-1.8-1.7-1-1.2l1 .8-1-1q-1-1.1-1.4-1.2a1 1 0 0 1-.8-.4q-.3-.5.2-.2t-.2-.4-1-1.4-1-.7q-.5 0-.4-.3.2-.4-.8-1.3-1-.7-.5-.5.5.3.2-.2-.2-.3-.9-.4-.5 0-.4-.3.2-.3-.6-1-.7-.6-.3-.5.6.3.3-.1t-1-.5q-.4 0-.3-.2 0-.4-.6-1t-.3-.5-.8-1-.8-1q.6.3.3-.1-.4-.5-.9-.5t-.4-.3-.3-.6-.5-.7-.3-.5q-.4 0-1.2-1l-.7-1 1 .8q.5.5-.9-1.4l-2.2-2.5q-.4-.5-.3-.7c.1 0-.5-1-1.5-1.9q-1.5-1.6-1.5-2.2 0-.4-.7-1l-1.7-1.6q-1-1.4 0-.6.8.8-.3-.7-.8-1.2-1.2-1.3-.3 0-.1-.4.1-.3-.4-.6t-.4-.6-.4-.5q-.5-.3-.4-.6.2-.4-.4-.6-.5-.2-.4-.6.2-.4-.3-.6t-.5-.6-.6-.7q-.7-.5-.6-1 .2-.6-.1-.4-.6.1-.4-.7c.2-.8-.9-1.8-1.2-1.6q-.3 0-.5-.4-.3-.6.2-.4l-.6-.7q-1.7-1.7-.6-1.3.4.2-.2-.3-.8-.7-.8-1.1 0-.6-1-1.5-.7-1-.6-1.4 0-.6-1-2-1.2-1.3-.9-1.1.6.3.3-.4-.2-.5-.6-.6t-.2-.3q.3-.5-.5-1.2-.6-.6-.5-1 .2-.1-.3-.2-.3 0-.2-.4.1-.3-.1-.4-.4-.1-.7-1.1-.2-1.1-.6-1.2t-.2-.4-.2-.4-.2-.4 0-.4-.4-.8q-.1-.9-.5-1.1t-.5-.6q.2-1-.3-.8-.7.1-.4-1.7 0-.4-.4-.3-.3.2-.1-.3 0-.6-.2-.6-.5 0-.4-.3c.1-.9-.1-1.7-.4-1.5-.5.3-1.3-2-1-2.6q.2-.4-.2-.1-.6.3-.3-.3.1-.6-.2-1l-.1-.5q.1-.3-.2-.4-.4 0-.1-.6.1-.7-.3-.4-.6.4-.2-.5.1-.8-.2-.8t-.3-.6q.2-.5 0-.6c-.5 0-1.4-2.9-1.3-4q0-.7-.4-.4t-.3-.8v-1q-.4 0-.2-.6.1-.5-.2-.6-.5 0-.3-.6t-.2-1.2-.2-1.2q.3-.5-.2-.3t-.2-.7q.2-1-.6-1.5t-.5 0q.5.9-.7-.2c-.6-.5-1.3-.7-3.3-.9q-.4 0-.3-.4.4-.6-1.4-.5a1 1 0 0 1-1-.5q-.3-.6-.7-.5-.5.2-1-.3a1 1 0 0 0-1-.3q-.7.2-.4-.2.4-.6-.8-.4l-.5-.4c-.3-.6-3.4-2-3.7-1.7q-.2 0-.2-.2t-.6-.7q-.6-.2-.4.3.3.4-.7-.5t-1-.6-.5-.3q-.3-.6-.7-.5t-1.4-.8q-.9-.8-1.3-.8-.4.2-.6-.3t-.6-.4-.6-.4-.6-.4-.4-.1q-.1-.4-1-1-1-.8-.8-.2.2.5-.3-.3-.7-.7-1-.6t-.4-.3-.4-.3q-.4-.1-1.4-1.1t-.7-.6q.1.5-.7-.4t-.6-.4q.2.4-1.3-1.1l-1.3-1.2q.3.6-.3 0t-.9-.5-.2-.4c0-.7-2.2-2.5-2.8-2.3q-.3 0-.2-.2a39 39 0 0 0-7.9-7.8q0-.5-.7-1.1t-.1-.4-.2-.5-1.3-.9q-.6 0-.4-.2t-.4-.9-.1-.3q.4.2-1-1.1t-1-1.2-1.1-1.9a9 9 0 0 0-2-2.2q-.3 0-.2-.4.2-.3-.5-.7-.8-.5-.8-1.3 0-.6-.4-.5-.3.1-.4-.6 0-.7-.6-1l-.6-.7c0-.7-.5-1.4-.8-1.2q-.2 0-.5-.4-.2-.7.2-.4t-.3-.4q-.7-.5-.7-1.1t-1-1.4q-.7-1-.6-1.5t-.2-.5-.3-.3c.2-.5-1-2.8-1.3-2.6q-.3.2 0-.5.1-.6-.3-.3t-.2-.4q.3-.7-.2-.4t-.2-.4q.1-.5-.2-.6t-.4-.3q.3-1.2-.4-1-.4.1-.4-.3c.2-1.2 0-2-.4-1.6q-.5.1-.2-.2.1-.5-.3-1-.6-.7-.4-1.2t-.2-.6q-.5 0-.3-.4.3-.3-.1-.4-.3 0-.2-.6.3-.6-.1-.4t-.6-.6q-.2-.6.1-.5.3.2.1-.4-.2-.5-.6-.6t-.2-.6-.2-.4q-.4.3-.1-.6t-.1-.6-.2-.6q.2-.6-.3-.7t-.2-.6q0-.5-.2-.6t-.2-.8-.2-.8 0-.6q0-.7-.3-.4-.5.3-.3-.6c0-.5-.3-2-.8-3.4s-.8-3-.7-3.5q.2-.8-.2-.8t-.2-1-.2-1-.2-1.2q.3-1-.2-1.1-.4 0-.3-.7 0-.7-.3-1.3-.3-.5.2-.2t0-.5-.2-1.6q0-.7-.2-.8t-.2-2v-2a176 176 0 0 1 .4-24.1q0-1.5.3-1.3.4.2.1-.9-.2-1 .3-1.7t-.1-.2q-.7.4-.1-.3.5-.5.2-.9-.1-.2.2-.6c.3-.1.6-1.2.6-2.4s.3-2.5.6-3q.4-.7.4-1.3-.2-.5.4-.4t0-.7q-.3-.7 0-.8t.1-1q-.1-1.2.3-.7.6.2.3-.4-.1-.5.2-.6t.1-.8q-.1-.8.2-.8.5 0 .3-.8-.1-.8.2-.5t.2-.6q-.1-.7.2-.6.4.3.2-.6t.2-.5q.4.2.2-.4t0-.7.2-.6q-.3-.7.3-.4.5.4.2-.1t0-.8q.5-.3.6-1t.3-1c.5-.4 1.6-3.1 1.2-3q-.4.2-.1-.3.1-.5.5-.6.3 0 .1-.6t.5-.8q.5-.2.4-.8t.2-.3q.6.3.2-.4-.1-.6.1-.4c.4.2 1-1 .6-1.4q0-.4.2-.4.5 0 .3-.3-.2-.4.4-.6.5-.3.4-.9-.2-.5.1-.3t.5-.3c0-1.2.1-1.4.8-2q.7-.7.4-1.1-.1-.4.2-.2.5.3.5-.1l.2-.8.1-.8q0-.3.4-.2t.4-.2q0-1 .6-1.3t.6-1 .6-1.4q.6-.6.4-.2-.3.5.5-.4.7-.8.6-1.4t.8-1.1q1-.7 1-1.2.1-.5.8-1t.7-.6.7-1.2.8-1.4q0-.5.4-.5c.6 0 2.1-2 1.8-2.3q-.2-.3.2 0 .4 0 1-.8.8-.9 1.2-.7t-.2-.5-.1-.5a41 41 0 0 0 8.6-8.5q.6.1 2.2-1.4l2-1.8q.4 0 .4-.6 0-.4.5-.5t.8-.5l.7-.6q.3 0 .3-.4-.1-.3.4 0 .7 0 1-.6.5-.7 1-.8.5 0 1.2-1t1.1-.8q.6 0 1.4-.6.9-.7.4-.5t.2-.4 1.4-.6 1-.6q.4-.6.7-.6 1.2.2.8-.4-.1-.3.2-.3.9 0 1.5-.8t.2 0 .4 0q.6-.5.7-.2t.4-.5 1-.8c.4 0 .6-.4.7-2.7.1-1.6 0-2.9-.2-2.9q-.2-.1-.2-2 0-1.7-.2-1.9t-.2-1.3q.1-1.3-.2-1.4t-.1-1q.1-1-.1-.9-.4.2-.4-1.2l-.2-2q0-.8-.3-.8-.3-.1-.4-.8c0-1.8-.2-2.5-.5-3q-.3-.4-.1-.8 0-.4-.2-.4t-.2-.6q.2-.5-.1-.6t-.4-1.2-.3-1.5q-.7-.5-.7-2 0-.8-.3-.8t-.1-.6q.1-.5-.2-.5t-.2-.6-.2-.6-.2-.6-.2-.6q-.5 0-.2-.4.1-.4-.4-1t-.5-1.2-.1-.5-.1-.7-.3-.3q-.6.3-.2-.6t-.2-.6-.4-1.1c0-.6-.9-2.7-1.5-3.2q-.5-.5-.6-1.5l-.2-1.5q0-.3-.4 0-.3 0-.5-.6c0-1.9-.7-3.3-1.2-3q-.4.2-.2-.3.1-.6-.3-1t-.3-.9-.3-.3-.2-.4-.2-.4-.2-.4c.3-.4-.5-2.4-1-2.4q-.3 0-.1-.4.1-.3-.2-.3t-.3-.3c.2-.6-1-2.9-1.3-2.6q-.3 0-.1-.4.2-.6-.4-.9a1 1 0 0 1-.7-1 1 1 0 0 0-.6-.9q-.5-.1-.3-.6c.3-.5-.9-2.7-1.5-2.7q-.3 0-.2-.3c.4-.3-.7-2.3-1.4-2.6a1 1 0 0 1-.4-.8q.2-.6-.4-.8-.5-.4-.8-1.4-.2-1-.6-1-.4.3-.4-.4c0-.9-1-2.2-1.3-1.8q-.2.1-.5-1t-.8-1.5q-.5-.2-.3-.6t-.4-.6q-.5-.1-.4-.5 0-.3-.4-1c-.6-.9-1-1-2.6-.6m6.7 99-1.5 1.5-1.4 1.3 1.3-1.5q1.8-1.8 1.6-1.3M281 280.8q-1.7 1.6-2 1.7 0-.2 1.6-1.7l1.9-1.8z"/><path d="M308 31.8q.8.6 1.1.6.2 0-.3-.6l-1.2-.5q-.2 0 .4.5m30.9 24.5 1.7 1.5-1.3-1.5q-1.5-1.6-1.8-1.6 0 .2 1.4 1.5M58.4 58.8l-2 2 2.1-1.9c1.9-1.8 2.2-2.2 2-2.2zM343.6 61q1.4 1.5 1.7 1.6l-1.4-1.6-1.7-1.5q0 .2 1.4 1.5m21 26q.6 1 1 .8 0-.3-.7-1l-1-1zm2.1 2.8q.1.6.8 1.6t.8.8l-.8-1.6q-.7-1-.8-.8M135 106.1q-1.2.9-.4.6c.7-.4 2-1.6 1.7-1.6q-.3 0-1.3 1m-16 13.3-1.3 1.5 1.4-1.3 1.5-1.5q.2-.5-1.6 1.3m266.1 5.6q.5 1.1.6 1c.2-.1-.5-2.2-.8-2.2zm.8 1.8q0 .4.5 1.3t.6.6l-.6-1.4q-.5-.8-.5-.5m-280.2 8.5q-1 1.3-.2.7c.7-.6 1.6-2 1.3-2zm293.9 56.1q0 1.2.2.7v-1.4q-.2-.5-.2.7m-85.9 8.4q0 2.3.2 1.3v-2.8q-.2-.9-.2 1.5m85.9 8.8q0 1.1.2.7v-1.4q-.2-.5-.2.7m-8.4 49.3q-.3 1-.1 1.4l.4-1.1q.2-1.1 0-1.4zm-110.8 22.9-1.6 1.7 2-1.7q1.6-1.7 1.5-1.8zm-249.1 27 .5 1q.6.7.6.4 0-.4-.6-1.1-.5-.6-.5-.4m131.7 1.2q0 .7.3 1.6c.4 1 .4 0 0-1.4q-.4-1.2-.3-.2m5 16.8.8 2q.6 1.2.5.5c-.3-1-1.3-3.1-1.3-2.5M55.5 338.4l1.2 1.3 1.3 1.1-1.1-1.2q-1.5-1.7-1.4-1.2m285.7 3.1-1.6 1.7 1.7-1.6c1.6-1.4 1.8-1.8 1.6-1.8zm-280.5 2.3 1.8 1.5-1.4-1.6-1.7-1.5zm123.9 14q.6 1.1.8 1.2l-.4-1.2-.8-1.2q-.2.2.4 1.2m79.9 7q.6 1.5 1 1.6l-.7-1.6q-.6-1.4-1-1.5zm-177.9 0q.8 1 1.1.8 0-.3-.9-1l-1-.6zm104.4 2.6 1 1.3c.4 0-.6-1.5-1.2-2q-.7-.5.2.7m-100.6 0 1.6.9q.3-.1-.8-.8l-1.6-.8q-.2.1.8.8m33.4 17.4c0 .3 2 1 2.3.8l-1-.6zm3.5 1.5 1.4.6q.3 0-.6-.6t-1.3-.5q-.3 0 .5.5m63.4 13.4h1.4q.5-.2-.7-.2t-.7.2m17.2 0h1.4q.5-.2-.7-.2t-.7.2"/></g></svg>
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="rowRef"
|
|
4
|
+
class="flex w-full justify-between items-center"
|
|
5
|
+
>
|
|
6
|
+
<!-- shrink-0 keeps the label at its natural width: letting flex shrink it by the fraction
|
|
7
|
+
of a pixel that rounding introduces is enough for Chromium to ellipsize a label that
|
|
8
|
+
fits. The cap is what makes an outsized label ellipsize instead of eating the row. -->
|
|
9
|
+
<div
|
|
10
|
+
v-if="label"
|
|
11
|
+
class="min-w-0 max-w-[45%] shrink-0"
|
|
12
|
+
>
|
|
13
|
+
<label
|
|
14
|
+
ref="labelRef"
|
|
15
|
+
class="block truncate text-start mr-6"
|
|
16
|
+
:title="label"
|
|
17
|
+
:class="theme === 'dark' ? 'text-white' : 'text-black'"
|
|
18
|
+
>{{ label }}</label>
|
|
19
|
+
</div>
|
|
20
|
+
<div v-else />
|
|
21
|
+
<slot name="insetElement" />
|
|
22
|
+
<!-- Shrinks far more eagerly than the label, so a tight row ellipsizes the button names
|
|
23
|
+
before it starts eating into the label. -->
|
|
24
|
+
<div class="flex items-center min-w-0 shrink-[1000]">
|
|
25
|
+
<div
|
|
26
|
+
v-if="infoTooltip"
|
|
27
|
+
class="relative group inline-flex items-center shrink-0 mr-2"
|
|
28
|
+
>
|
|
29
|
+
<span
|
|
30
|
+
class="mdi mdi-information-outline text-[16px] opacity-60 cursor-help"
|
|
31
|
+
:class="theme === 'dark' ? 'text-white' : 'text-black'"
|
|
32
|
+
/>
|
|
33
|
+
<div
|
|
34
|
+
class="absolute bottom-full mb-1 right-0 hidden group-hover:block w-max max-w-[280px] px-2 py-1 text-xs rounded bg-gray-700 text-white z-[1000]"
|
|
35
|
+
>
|
|
36
|
+
{{ infoTooltip }}
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
<div
|
|
40
|
+
ref="trackRef"
|
|
41
|
+
class="relative flex min-w-0 justify-end overflow-hidden rounded-[6px] bluevue-elevation-1 z-[666]"
|
|
42
|
+
:class="[theme === 'dark' ? 'bg-[#464646AA]' : 'bg-[#00000011]', disabled ? 'opacity-30 pointer-events-none' : '']"
|
|
43
|
+
:style="{ height: height || (density === 'compact' ? '24px' : '30px') }"
|
|
44
|
+
>
|
|
45
|
+
<div
|
|
46
|
+
id="border-releif"
|
|
47
|
+
class="absolute left-[-20px] top-0 h-full w-[6px] bg-[#6699cc] z-[20] pointer-events-none"
|
|
48
|
+
/>
|
|
49
|
+
<template
|
|
50
|
+
v-for="(btn, idx) in buttonItems"
|
|
51
|
+
:key="btn.name"
|
|
52
|
+
>
|
|
53
|
+
<button
|
|
54
|
+
:disabled="disabled || btn.disabled"
|
|
55
|
+
:title="btn.name"
|
|
56
|
+
class="flex min-w-0 items-center justify-center text-sm font-medium transition-colors duration-200"
|
|
57
|
+
:class="[
|
|
58
|
+
// A group with no room left falls back to the tightest inset whatever the
|
|
59
|
+
// density asks for, since the alternative is cutting into the names.
|
|
60
|
+
isTight ? DENSITY_PADDING.compact.class : DENSITY_PADDING[density || 'comfortable'].class,
|
|
61
|
+
// The active choice is the one worth reading at a glance, so it keeps its full
|
|
62
|
+
// name and the rest give up the room a crowded group needs.
|
|
63
|
+
selected[idx] ? 'shrink-0' : '',
|
|
64
|
+
selected[idx] ? 'text-white' : theme === 'dark' ? 'text-[#ffffff99]' : 'text-[#00000066]',
|
|
65
|
+
selected[idx] && type === 'switch' ? 'bluevue-elevation-5' : '',
|
|
66
|
+
disabled || btn.disabled ? 'cursor-not-allowed' : 'cursor-pointer',
|
|
67
|
+
// Only the button's own state fades it: a disabled group is faded whole by the
|
|
68
|
+
// track below, and dimming twice over would leave the names unreadable.
|
|
69
|
+
btn.disabled ? 'opacity-30' : '',
|
|
70
|
+
]"
|
|
71
|
+
:style="{ backgroundColor: selected[idx] ? btn.activeColor || 'var(--bluevue-primary)' : undefined }"
|
|
72
|
+
@click="onButtonClick(idx)"
|
|
73
|
+
@contextmenu.prevent="requestContextMenu(idx, $event)"
|
|
74
|
+
@pointerdown="startLongPress(idx, $event)"
|
|
75
|
+
@pointerup="cancelLongPress"
|
|
76
|
+
@pointerleave="cancelLongPress"
|
|
77
|
+
@pointercancel="cancelLongPress"
|
|
78
|
+
>
|
|
79
|
+
<div class="relative group inline-block min-w-0">
|
|
80
|
+
<p
|
|
81
|
+
data-bbg-label
|
|
82
|
+
class="truncate"
|
|
83
|
+
:class="[density === 'compact' ? 'text-[10px]' : 'text-xs', isWide ? 'max-w-[150px]' : '']"
|
|
84
|
+
>
|
|
85
|
+
{{ btn.name }}
|
|
86
|
+
</p>
|
|
87
|
+
<div
|
|
88
|
+
v-if="btn.tooltip"
|
|
89
|
+
class="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 hidden group-hover:block whitespace-no-wrap px-2 py-1 text-xs rounded bg-gray-700 text-white"
|
|
90
|
+
>
|
|
91
|
+
{{ btn.tooltip }}
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</button>
|
|
95
|
+
<div
|
|
96
|
+
v-if="idx < buttonItems.length - 1"
|
|
97
|
+
class="w-[1px] shrink-0 bg-[#FFFFFF22] my-2"
|
|
98
|
+
/>
|
|
99
|
+
</template>
|
|
100
|
+
<div
|
|
101
|
+
v-if="buttonsMenu?.length"
|
|
102
|
+
class="w-[1px] shrink-0 bg-[#FFFFFF22] my-2 mr-[3px]"
|
|
103
|
+
/>
|
|
104
|
+
<template v-if="buttonsMenu?.length">
|
|
105
|
+
<button
|
|
106
|
+
ref="menuAnchorRef"
|
|
107
|
+
v-bind="menuActivatorProps"
|
|
108
|
+
type="button"
|
|
109
|
+
title="More options"
|
|
110
|
+
class="shrink-0 px-0 flex items-center justify-center h-full cursor-pointer"
|
|
111
|
+
:class="theme === 'dark' ? 'text-white' : 'text-black'"
|
|
112
|
+
>
|
|
113
|
+
<span class="self-center mdi mdi-menu-right text-[20px] mr-[2px] opacity-80" />
|
|
114
|
+
</button>
|
|
115
|
+
<div
|
|
116
|
+
:id="menuPopoverId"
|
|
117
|
+
ref="menuPopoverRef"
|
|
118
|
+
popover
|
|
119
|
+
class="bluevue-popover"
|
|
120
|
+
:style="menuFloatingStyles"
|
|
121
|
+
@toggle="onMenuToggle"
|
|
122
|
+
>
|
|
123
|
+
<ul
|
|
124
|
+
class="bluevue-elevation-5 max-h-[60vh] overflow-y-auto border-[1px] rounded-[4px] border-[#FFFFFF22]"
|
|
125
|
+
:class="[
|
|
126
|
+
theme === 'dark' ? 'text-[#FFFFFF99] bg-[var(--bluevue-surface)]' : 'text-black bg-white',
|
|
127
|
+
isMenuPositioned ? 'opacity-100' : 'opacity-0',
|
|
128
|
+
]"
|
|
129
|
+
>
|
|
130
|
+
<li
|
|
131
|
+
v-for="(item, idx) in buttonsMenu"
|
|
132
|
+
:key="item.name"
|
|
133
|
+
>
|
|
134
|
+
<button
|
|
135
|
+
:disabled="item.menuItemDisabled"
|
|
136
|
+
type="button"
|
|
137
|
+
class="block w-full text-left whitespace-nowrap px-4 py-2 text-[14px]"
|
|
138
|
+
:class="[
|
|
139
|
+
idx < buttonsMenu.length - 1 ? 'border-b border-white' : '',
|
|
140
|
+
theme === 'dark' ? 'hover:bg-[#333333]' : 'hover:bg-gray-100',
|
|
141
|
+
item.menuItemDisabled ? 'opacity-30 cursor-not-allowed' : 'cursor-pointer',
|
|
142
|
+
]"
|
|
143
|
+
@click="runMenuItem(item)"
|
|
144
|
+
>
|
|
145
|
+
{{ item.name }}
|
|
146
|
+
</button>
|
|
147
|
+
</li>
|
|
148
|
+
</ul>
|
|
149
|
+
</div>
|
|
150
|
+
</template>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</template>
|
|
155
|
+
<script setup lang="ts">
|
|
156
|
+
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
157
|
+
|
|
158
|
+
import { useBluePopover } from '../composables/useBluePopover'
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* One button in the group
|
|
162
|
+
*/
|
|
163
|
+
interface ButtonItem {
|
|
164
|
+
/** Name of the button, displayed as text */
|
|
165
|
+
name: string
|
|
166
|
+
/** Optional tooltip text displayed on hover */
|
|
167
|
+
tooltip?: string
|
|
168
|
+
/** Whether this button is pre-selected (only for 'switch' type) */
|
|
169
|
+
preSelected?: boolean
|
|
170
|
+
/** Optional color for the button when active */
|
|
171
|
+
activeColor?: string
|
|
172
|
+
/** Whether the button is disabled */
|
|
173
|
+
disabled?: boolean
|
|
174
|
+
/** Callback when the button is selected */
|
|
175
|
+
onSelected?: () => void
|
|
176
|
+
/** Custom options to handle button item press */
|
|
177
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
178
|
+
options?: Record<string, any>
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* One item in the menu
|
|
183
|
+
*/
|
|
184
|
+
interface MenuItem {
|
|
185
|
+
/** Name of the menu item, displayed as text */
|
|
186
|
+
name: string
|
|
187
|
+
/** Callback when the menu item is clicked */
|
|
188
|
+
action: () => void
|
|
189
|
+
/** Disable the menu item */
|
|
190
|
+
menuItemDisabled?: boolean
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const props = defineProps<{
|
|
194
|
+
/** List of buttons in the group */
|
|
195
|
+
buttonItems: ButtonItem[]
|
|
196
|
+
/** Optional menu items to display in a dropdown */
|
|
197
|
+
buttonsMenu?: MenuItem[]
|
|
198
|
+
/** Whether the entire button group is disabled */
|
|
199
|
+
disabled?: boolean
|
|
200
|
+
/** Theme of the button group */
|
|
201
|
+
theme?: 'light' | 'dark'
|
|
202
|
+
/** Type of button group, 'switch' for single selection or 'toggle' for multiple selections */
|
|
203
|
+
type: 'switch' | 'toggle'
|
|
204
|
+
/** Height of the button group container */
|
|
205
|
+
height?: string
|
|
206
|
+
/** Label text on the left side of the button group */
|
|
207
|
+
label?: string
|
|
208
|
+
/** Optional info tooltip shown via an info icon next to the control. */
|
|
209
|
+
infoTooltip?: string
|
|
210
|
+
/**
|
|
211
|
+
* How much room each button gives its name (default 'comfortable'). 'compact' also makes the
|
|
212
|
+
* group shorter and its labels smaller, for rows where the group is a secondary control.
|
|
213
|
+
*/
|
|
214
|
+
density?: 'compact' | 'regular' | 'comfortable'
|
|
215
|
+
}>()
|
|
216
|
+
|
|
217
|
+
const emit = defineEmits<{
|
|
218
|
+
(e: 'update:selected', value: boolean[]): void
|
|
219
|
+
/**
|
|
220
|
+
* A button was right-clicked or held down, with the pointer position to place a menu at.
|
|
221
|
+
* Emitted instead of the selection, so holding a button never also activates it.
|
|
222
|
+
*/
|
|
223
|
+
(e: 'context-menu', value: { item: ButtonItem; index: number; x: number; y: number }): void
|
|
224
|
+
}>()
|
|
225
|
+
|
|
226
|
+
const selected = ref<boolean[]>([])
|
|
227
|
+
|
|
228
|
+
const {
|
|
229
|
+
anchorRef: menuAnchorRef,
|
|
230
|
+
popoverRef: menuPopoverRef,
|
|
231
|
+
popoverId: menuPopoverId,
|
|
232
|
+
activatorProps: menuActivatorProps,
|
|
233
|
+
isPositioned: isMenuPositioned,
|
|
234
|
+
floatingStyles: menuFloatingStyles,
|
|
235
|
+
hide: hideMenu,
|
|
236
|
+
onToggle: onMenuToggle,
|
|
237
|
+
} = useBluePopover()
|
|
238
|
+
|
|
239
|
+
// Long enough not to fire on a normal tap, short enough to feel like a press-and-hold.
|
|
240
|
+
const LONG_PRESS_MS = 500
|
|
241
|
+
let longPressTimer: number | null = null
|
|
242
|
+
let longPressFired = false
|
|
243
|
+
|
|
244
|
+
// The inset each density gives a button name, paired with the total width it costs so the
|
|
245
|
+
// measurements below can reason about the group without reading it back from the DOM.
|
|
246
|
+
const DENSITY_PADDING = {
|
|
247
|
+
compact: { class: 'px-2', total: 16 },
|
|
248
|
+
regular: { class: 'px-3', total: 24 },
|
|
249
|
+
comfortable: { class: 'px-4', total: 32 },
|
|
250
|
+
} as const
|
|
251
|
+
|
|
252
|
+
// Once the buttons' natural width would exceed this, cap each label so long names
|
|
253
|
+
// ellipsize instead of letting the group sprawl (or clip) past the panel.
|
|
254
|
+
const GROUP_WIDTH_LIMIT = 850
|
|
255
|
+
const LABEL_MARGIN = 24 // mr-6 on the label
|
|
256
|
+
const rowRef = ref<HTMLElement | null>(null)
|
|
257
|
+
const labelRef = ref<HTMLElement | null>(null)
|
|
258
|
+
const trackRef = ref<HTMLElement | null>(null)
|
|
259
|
+
const isWide = ref(false)
|
|
260
|
+
const isTight = ref(false)
|
|
261
|
+
let resizeObserver: ResizeObserver | null = null
|
|
262
|
+
|
|
263
|
+
const measureWidth = (): void => {
|
|
264
|
+
const track = trackRef.value
|
|
265
|
+
const row = rowRef.value
|
|
266
|
+
if (!track || !row) return
|
|
267
|
+
// Each label keeps its full text width in scrollWidth even while ellipsized, so the
|
|
268
|
+
// natural width is independent of the cap we apply, avoiding a measure/toggle loop.
|
|
269
|
+
const labels = track.querySelectorAll<HTMLElement>('[data-bbg-label]')
|
|
270
|
+
const padding = DENSITY_PADDING[props.density || 'comfortable'].total
|
|
271
|
+
let natural = 0
|
|
272
|
+
labels.forEach((label) => {
|
|
273
|
+
natural += label.scrollWidth + padding
|
|
274
|
+
})
|
|
275
|
+
natural += Math.max(0, labels.length - 1) // 1px separators between buttons
|
|
276
|
+
isWide.value = natural > GROUP_WIDTH_LIMIT
|
|
277
|
+
|
|
278
|
+
// Room the track could ever have: the row minus the label at full text width and whatever
|
|
279
|
+
// else sits beside the track. Measured that way, and always against the density's own
|
|
280
|
+
// padding, the answer does not depend on the padding currently applied, so it cannot
|
|
281
|
+
// oscillate between the two.
|
|
282
|
+
let occupied = labelRef.value ? labelRef.value.scrollWidth + LABEL_MARGIN : 0
|
|
283
|
+
for (const child of Array.from(row.children)) {
|
|
284
|
+
if (!child.contains(track)) continue
|
|
285
|
+
occupied += child.clientWidth - track.clientWidth
|
|
286
|
+
}
|
|
287
|
+
isTight.value = natural > row.clientWidth - occupied
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const initSelected = (): void => {
|
|
291
|
+
const items = props.buttonItems
|
|
292
|
+
if (props.type === 'switch') {
|
|
293
|
+
const first = items.findIndex((b) => b.preSelected)
|
|
294
|
+
const idx = first >= 0 ? first : 0
|
|
295
|
+
selected.value = items.map((_, i) => i === idx)
|
|
296
|
+
} else {
|
|
297
|
+
selected.value = items.map((b) => !!b.preSelected)
|
|
298
|
+
}
|
|
299
|
+
emit('update:selected', selected.value)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const toggleButton = (idx: number): void => {
|
|
303
|
+
if (props.disabled || props.buttonItems[idx].disabled) return
|
|
304
|
+
const btn = props.buttonItems[idx]
|
|
305
|
+
if (props.type === 'switch') {
|
|
306
|
+
if (!selected.value[idx]) {
|
|
307
|
+
selected.value = selected.value.map((_, i) => i === idx)
|
|
308
|
+
btn.onSelected?.()
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
selected.value[idx] = !selected.value[idx]
|
|
312
|
+
if (selected.value[idx]) btn.onSelected?.()
|
|
313
|
+
}
|
|
314
|
+
emit('update:selected', selected.value)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const requestContextMenu = (idx: number, event: MouseEvent | PointerEvent): void => {
|
|
318
|
+
if (props.disabled || props.buttonItems[idx].disabled) return
|
|
319
|
+
emit('context-menu', { item: props.buttonItems[idx], index: idx, x: event.clientX, y: event.clientY })
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const cancelLongPress = (): void => {
|
|
323
|
+
if (longPressTimer !== null) {
|
|
324
|
+
clearTimeout(longPressTimer)
|
|
325
|
+
longPressTimer = null
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const startLongPress = (idx: number, event: PointerEvent): void => {
|
|
330
|
+
if (props.disabled || props.buttonItems[idx].disabled) return
|
|
331
|
+
cancelLongPress()
|
|
332
|
+
longPressFired = false
|
|
333
|
+
const { clientX, clientY } = event
|
|
334
|
+
longPressTimer = window.setTimeout(() => {
|
|
335
|
+
longPressTimer = null
|
|
336
|
+
longPressFired = true
|
|
337
|
+
emit('context-menu', { item: props.buttonItems[idx], index: idx, x: clientX, y: clientY })
|
|
338
|
+
}, LONG_PRESS_MS)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const onButtonClick = (idx: number): void => {
|
|
342
|
+
// The click that ends a long press must not also select the button it was held on.
|
|
343
|
+
if (longPressFired) {
|
|
344
|
+
longPressFired = false
|
|
345
|
+
return
|
|
346
|
+
}
|
|
347
|
+
if (!props.buttonItems[idx].disabled) toggleButton(idx)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const runMenuItem = (item: MenuItem): void => {
|
|
351
|
+
item.action()
|
|
352
|
+
hideMenu()
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
onMounted(() => {
|
|
356
|
+
initSelected()
|
|
357
|
+
nextTick(measureWidth)
|
|
358
|
+
// The first measurement runs against whatever font is available, and a fallback is wide
|
|
359
|
+
// enough to call a group crowded that is not. Measure again once the real font lands.
|
|
360
|
+
document.fonts?.ready.then(measureWidth)
|
|
361
|
+
if (typeof ResizeObserver !== 'undefined' && trackRef.value) {
|
|
362
|
+
resizeObserver = new ResizeObserver(() => measureWidth())
|
|
363
|
+
resizeObserver.observe(trackRef.value)
|
|
364
|
+
}
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
onBeforeUnmount(() => {
|
|
368
|
+
resizeObserver?.disconnect()
|
|
369
|
+
cancelLongPress()
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
watch(
|
|
373
|
+
() => props.buttonItems.length,
|
|
374
|
+
initSelected,
|
|
375
|
+
{ deep: true, immediate: true }
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
watch(
|
|
379
|
+
() => props.buttonItems.map((item) => item.name).join('|'),
|
|
380
|
+
() => nextTick(measureWidth)
|
|
381
|
+
)
|
|
382
|
+
</script>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="rounded-lg overflow-hidden">
|
|
3
|
+
<div
|
|
4
|
+
class="flex items-center justify-between bg-transparent cursor-pointer select-none px-3 my-2"
|
|
5
|
+
@click="togglePanel"
|
|
6
|
+
>
|
|
7
|
+
<div class="flex-1 flex items-center">
|
|
8
|
+
<div
|
|
9
|
+
class="flex-1 h-px"
|
|
10
|
+
:class="props.theme === 'dark' ? 'bg-[#ffffff22]' : 'bg-[#00000033]'"
|
|
11
|
+
/>
|
|
12
|
+
<span
|
|
13
|
+
class="mx-3 min-w-0 truncate text-sm font-medium opacity-60"
|
|
14
|
+
:title="title"
|
|
15
|
+
:class="props.theme === 'dark' ? 'text-white' : 'text-black'"
|
|
16
|
+
>{{ title }}</span>
|
|
17
|
+
<div
|
|
18
|
+
class="flex-1 h-px"
|
|
19
|
+
:class="props.theme === 'dark' ? 'bg-[#ffffff11]' : 'bg-[#00000033]'"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
<span
|
|
23
|
+
class="mdi ml-3 text-[24px] leading-none opacity-40"
|
|
24
|
+
:class="[
|
|
25
|
+
isOpen ? 'mdi-menu-up' : 'mdi-menu-down',
|
|
26
|
+
props.theme === 'dark' ? 'text-white' : 'text-black',
|
|
27
|
+
]"
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
<transition name="bluevue-expand">
|
|
31
|
+
<div
|
|
32
|
+
v-show="isOpen"
|
|
33
|
+
class="px-13 my-6 pb-2"
|
|
34
|
+
:class="props.theme === 'dark' ? 'border-[#555555]' : 'border-[#dddddd]'"
|
|
35
|
+
>
|
|
36
|
+
<slot />
|
|
37
|
+
</div>
|
|
38
|
+
</transition>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script setup lang="ts">
|
|
43
|
+
import { ref, watch } from 'vue'
|
|
44
|
+
|
|
45
|
+
const props = defineProps<{
|
|
46
|
+
/** Panel title */
|
|
47
|
+
title: string
|
|
48
|
+
/** Initial open state */
|
|
49
|
+
expanded?: boolean
|
|
50
|
+
/** 'light' or 'dark' theme */
|
|
51
|
+
theme?: 'light' | 'dark'
|
|
52
|
+
}>()
|
|
53
|
+
|
|
54
|
+
const emit = defineEmits<{
|
|
55
|
+
(e: 'update:expanded', value: boolean): void
|
|
56
|
+
}>()
|
|
57
|
+
|
|
58
|
+
const isOpen = ref(props.expanded ?? true)
|
|
59
|
+
|
|
60
|
+
const togglePanel = (): void => {
|
|
61
|
+
isOpen.value = !isOpen.value
|
|
62
|
+
emit('update:expanded', isOpen.value)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
watch(
|
|
66
|
+
() => props.expanded,
|
|
67
|
+
(val) => {
|
|
68
|
+
if (val !== undefined) isOpen.value = val
|
|
69
|
+
},
|
|
70
|
+
{ immediate: true }
|
|
71
|
+
)
|
|
72
|
+
</script>
|