vue-pane 0.0.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.
Files changed (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +424 -0
  3. package/dist/src/components/PButton.vue.d.ts +11 -0
  4. package/dist/src/components/PCheckbox.vue.d.ts +15 -0
  5. package/dist/src/components/PColor.vue.d.ts +16 -0
  6. package/dist/src/components/PFolder.vue.d.ts +27 -0
  7. package/dist/src/components/PGraph.vue.d.ts +10 -0
  8. package/dist/src/components/PLabel.vue.d.ts +17 -0
  9. package/dist/src/components/PMonitor.vue.d.ts +8 -0
  10. package/dist/src/components/PMonitorMulti.vue.d.ts +8 -0
  11. package/dist/src/components/PNumber.vue.d.ts +18 -0
  12. package/dist/src/components/PPoint2d.vue.d.ts +26 -0
  13. package/dist/src/components/PSelect.vue.d.ts +19 -0
  14. package/dist/src/components/PSeparator.vue.d.ts +3 -0
  15. package/dist/src/components/PSlider.vue.d.ts +18 -0
  16. package/dist/src/components/PTab.vue.d.ts +25 -0
  17. package/dist/src/components/PText.vue.d.ts +15 -0
  18. package/dist/src/components/PTooltipIcon.vue.d.ts +3 -0
  19. package/dist/src/components/VPane.vue.d.ts +28 -0
  20. package/dist/src/composables/useFoldable.d.ts +5 -0
  21. package/dist/src/composables/usePaneConfig.d.ts +8 -0
  22. package/dist/src/composables/usePickerFold.d.ts +2 -0
  23. package/dist/src/composables/useTooltip.d.ts +19 -0
  24. package/dist/src/index.d.ts +19 -0
  25. package/dist/vue-pane.css +2 -0
  26. package/dist/vue-pane.js +3076 -0
  27. package/dist/vue-pane.umd.cjs +1 -0
  28. package/package.json +79 -0
  29. package/src/components/PButton.vue +53 -0
  30. package/src/components/PCheckbox.vue +37 -0
  31. package/src/components/PColor.vue +107 -0
  32. package/src/components/PConfig.vue +10 -0
  33. package/src/components/PFolder.vue +81 -0
  34. package/src/components/PGraph.vue +49 -0
  35. package/src/components/PLabel.vue +50 -0
  36. package/src/components/PMonitor.vue +28 -0
  37. package/src/components/PMonitorMulti.vue +30 -0
  38. package/src/components/PNumber.vue +162 -0
  39. package/src/components/PPoint2d.vue +191 -0
  40. package/src/components/PSelect.vue +44 -0
  41. package/src/components/PSeparator.vue +8 -0
  42. package/src/components/PSlider.vue +96 -0
  43. package/src/components/PTab.vue +73 -0
  44. package/src/components/PText.vue +30 -0
  45. package/src/components/PTooltipIcon.vue +30 -0
  46. package/src/components/VPane.vue +61 -0
  47. package/src/composables/useFoldable.ts +128 -0
  48. package/src/composables/usePaneConfig.ts +25 -0
  49. package/src/composables/usePickerFold.ts +46 -0
  50. package/src/composables/useTooltip.ts +27 -0
  51. package/src/index.ts +38 -0
  52. package/src/styles/_vp.scss +12 -0
  53. package/src/styles/common/_defs.scss +56 -0
  54. package/src/styles/index.scss +1 -0
  55. package/src/styles/view/_button.scss +12 -0
  56. package/src/styles/view/_checkbox.scss +54 -0
  57. package/src/styles/view/_color.scss +57 -0
  58. package/src/styles/view/_folder.scss +70 -0
  59. package/src/styles/view/_graph.scss +11 -0
  60. package/src/styles/view/_label.scss +37 -0
  61. package/src/styles/view/_list.scss +17 -0
  62. package/src/styles/view/_log.scss +13 -0
  63. package/src/styles/view/_monitor-multi.scss +18 -0
  64. package/src/styles/view/_number.scss +110 -0
  65. package/src/styles/view/_point-2d.scss +61 -0
  66. package/src/styles/view/_root.scss +126 -0
  67. package/src/styles/view/_separator.scss +15 -0
  68. package/src/styles/view/_slider.scss +32 -0
  69. package/src/styles/view/_tab.scss +139 -0
  70. package/src/styles/view/_text.scss +24 -0
  71. package/src/styles/view/_tooltip.scss +17 -0
  72. package/src/styles/view/_views.scss +2 -0
  73. package/src/styles/view/placeholder/_button.scss +28 -0
  74. package/src/styles/view/placeholder/_container.scss +80 -0
  75. package/src/styles/view/placeholder/_folder.scss +102 -0
  76. package/src/styles/view/placeholder/_input.scss +26 -0
  77. package/src/styles/view/placeholder/_list.scss +35 -0
  78. package/src/styles/view/placeholder/_monitor.scss +26 -0
  79. package/src/styles/view/placeholder/_texts.scss +11 -0
  80. package/src/styles/view/placeholder/_theme.scss +111 -0
@@ -0,0 +1,61 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref } from 'vue'
3
+ import { useFoldable } from '../composables/useFoldable'
4
+ import { type PaneConfig, providePaneConfig } from '../composables/usePaneConfig'
5
+
6
+ const expandedModel = defineModel<boolean>('expanded', { default: undefined })
7
+
8
+ const {
9
+ title,
10
+ id,
11
+ disabled,
12
+ config,
13
+ } = defineProps<{
14
+ title?: string
15
+ id?: string
16
+ disabled?: boolean
17
+ config?: PaneConfig
18
+ }>()
19
+
20
+ if (config) {
21
+ providePaneConfig(config)
22
+ }
23
+
24
+ const key = id ?? title
25
+ const hasTitle = computed(() => !!title)
26
+ const containerRef = ref<HTMLElement | null>(null)
27
+ const { isExpanded, toggle } = useFoldable(
28
+ containerRef,
29
+ expandedModel,
30
+ key ? `vp-pane-${key}` : undefined,
31
+ )
32
+ </script>
33
+ <template>
34
+ <div
35
+ class="vp-pane"
36
+ :class="{
37
+ 'vp-pane--expanded': isExpanded,
38
+ 'vp-pane--no-title': !hasTitle,
39
+ 'vp--disabled': disabled,
40
+ }"
41
+ >
42
+ <button
43
+ v-if="hasTitle"
44
+ class="vp-pane__title"
45
+ @click="toggle"
46
+ >
47
+ {{ title }}
48
+ <div class="vp-pane__chevron" />
49
+ </button>
50
+ <div
51
+ ref="containerRef"
52
+ class="vp-pane__content"
53
+ >
54
+ <slot />
55
+ </div>
56
+ </div>
57
+ </template>
58
+ <style lang="scss">
59
+ @use '../styles/view/root';
60
+ @use '../styles/view/tooltip';
61
+ </style>
@@ -0,0 +1,128 @@
1
+ import type { Ref } from 'vue'
2
+ import { nextTick, onMounted, ref, watch } from 'vue'
3
+ import { usePaneConfig } from './usePaneConfig.ts'
4
+
5
+ function measureExpandedHeight(el: HTMLElement, expandedClass: string): number {
6
+ const parent = el.parentElement
7
+ if (!parent) return 0
8
+
9
+ const wasExpanded = parent.classList.contains(expandedClass)
10
+
11
+ // Temporarily disable transitions and apply expanded state to measure true height
12
+ el.style.transition = 'none'
13
+ if (!wasExpanded) {
14
+ parent.classList.add(expandedClass)
15
+ el.style.height = 'auto'
16
+ }
17
+ void el.offsetHeight
18
+ const height = el.clientHeight
19
+
20
+ if (!wasExpanded) {
21
+ parent.classList.remove(expandedClass)
22
+ el.style.height = ''
23
+ }
24
+ void el.offsetHeight
25
+ el.style.transition = ''
26
+
27
+ return height
28
+ }
29
+
30
+ export function useFoldable(
31
+ containerRef: Ref<HTMLElement | null>,
32
+ expandedRef: Ref<boolean>,
33
+ storageKey?: string,
34
+ expandedClass = 'vp-folder--expanded',
35
+ ): {
36
+ isExpanded: Ref<boolean>
37
+ toggle: () => void
38
+ } {
39
+ let stored: string | null = null
40
+ if (storageKey) {
41
+ stored = localStorage?.getItem?.(storageKey) ?? null
42
+ }
43
+ const config = usePaneConfig()
44
+ const onToggle = (val: boolean) => expandedRef.value = val
45
+ const initialPropValue = expandedRef.value as boolean | undefined
46
+ const isExpanded = ref(
47
+ initialPropValue !== undefined
48
+ ? initialPropValue
49
+ : stored !== null
50
+ ? stored === 'true'
51
+ : config.expandedDefault ?? true,
52
+ )
53
+
54
+ watch(isExpanded, (val) => {
55
+ if (storageKey && typeof localStorage !== 'undefined') {
56
+ localStorage.setItem(storageKey, String(val))
57
+ }
58
+ onToggle(val)
59
+ })
60
+
61
+ onMounted(() => {
62
+ const el = containerRef.value
63
+ if (el && isExpanded.value) {
64
+ el.style.height = 'auto'
65
+ }
66
+ })
67
+
68
+ function animateExpand(el: HTMLElement) {
69
+ const targetHeight = measureExpandedHeight(el, expandedClass)
70
+ isExpanded.value = true
71
+
72
+ nextTick(() => {
73
+ if (targetHeight === 0) {
74
+ el.style.height = 'auto'
75
+ return
76
+ }
77
+ // Pin padding to 0 inline so both height and padding can animate from 0
78
+ el.style.paddingTop = '0'
79
+ el.style.paddingBottom = '0'
80
+ void el.offsetHeight
81
+
82
+ el.style.height = targetHeight + 'px'
83
+ el.style.paddingTop = ''
84
+ el.style.paddingBottom = ''
85
+
86
+ el.addEventListener('transitionend', (e: TransitionEvent) => {
87
+ if (e.propertyName === 'height' && isExpanded.value) {
88
+ el.style.height = 'auto'
89
+ }
90
+ }, { once: true })
91
+ })
92
+ }
93
+
94
+ function animateCollapse(el: HTMLElement) {
95
+ // Lock to px so height: auto → 0 is animatable
96
+ el.style.transition = 'none'
97
+ el.style.height = el.clientHeight + 'px'
98
+ void el.offsetHeight
99
+ el.style.transition = ''
100
+ void el.offsetHeight
101
+
102
+ el.style.height = '0'
103
+ isExpanded.value = false
104
+
105
+ el.addEventListener('transitionend', (e: TransitionEvent) => {
106
+ if (e.propertyName === 'height') {
107
+ el.style.height = ''
108
+ }
109
+ }, { once: true })
110
+ }
111
+
112
+ watch(() => expandedRef.value as boolean | undefined, (val) => {
113
+ if (val === undefined || val === isExpanded.value) return
114
+ const el = containerRef.value
115
+ if (!el) return
116
+ if (val) animateExpand(el)
117
+ else animateCollapse(el)
118
+ })
119
+
120
+ function toggle() {
121
+ const el = containerRef.value
122
+ if (!el) return
123
+ if (isExpanded.value) animateCollapse(el)
124
+ else animateExpand(el)
125
+ }
126
+
127
+ return { isExpanded, toggle }
128
+ }
@@ -0,0 +1,25 @@
1
+ import { type Component, inject, type InjectionKey, provide } from 'vue'
2
+ import PTooltipIcon from '../components/PTooltipIcon.vue'
3
+
4
+ export interface PaneConfig {
5
+ readonly tooltipIcon?: Component | null
6
+ readonly expandedDefault?: boolean
7
+ }
8
+
9
+ const DEFAULTS: PaneConfig = {
10
+ expandedDefault: true,
11
+ tooltipIcon: PTooltipIcon,
12
+ }
13
+
14
+ export const PANE_CONFIG_KEY: InjectionKey<PaneConfig> = Symbol('vp-config')
15
+
16
+ export function usePaneConfig(): PaneConfig {
17
+ return inject(PANE_CONFIG_KEY, DEFAULTS)
18
+ }
19
+
20
+ export function providePaneConfig(config: Partial<PaneConfig> | null = null): void {
21
+ provide(PANE_CONFIG_KEY, {
22
+ ...usePaneConfig(),
23
+ ...config,
24
+ } as PaneConfig)
25
+ }
@@ -0,0 +1,46 @@
1
+ import { ref, watch } from 'vue'
2
+ import type { Ref } from 'vue'
3
+
4
+ export function usePickerFold(
5
+ panelRef: Ref<HTMLElement | null>,
6
+ isOpen: Ref<boolean>,
7
+ ): Ref<boolean> {
8
+ const isComplete = ref(false)
9
+
10
+ watch(isOpen, (open) => {
11
+ const el = panelRef.value
12
+ if (!el) return
13
+
14
+ isComplete.value = false
15
+
16
+ if (open) {
17
+ el.style.transition = 'none'
18
+ el.style.height = 'auto'
19
+ void el.offsetHeight
20
+ const h = el.clientHeight
21
+ el.style.height = '0'
22
+ void el.offsetHeight
23
+ el.style.transition = ''
24
+ void el.offsetHeight
25
+ el.style.height = h + 'px'
26
+ el.addEventListener('transitionend', (e: TransitionEvent) => {
27
+ if (e.propertyName === 'height') {
28
+ el.style.height = 'auto'
29
+ isComplete.value = true
30
+ }
31
+ }, { once: true })
32
+ } else {
33
+ el.style.transition = 'none'
34
+ el.style.height = el.clientHeight + 'px'
35
+ void el.offsetHeight
36
+ el.style.transition = ''
37
+ void el.offsetHeight
38
+ el.style.height = '0'
39
+ el.addEventListener('transitionend', (e: TransitionEvent) => {
40
+ if (e.propertyName === 'height') el.style.height = ''
41
+ }, { once: true })
42
+ }
43
+ })
44
+
45
+ return isComplete
46
+ }
@@ -0,0 +1,27 @@
1
+ import { ref, useTemplateRef } from 'vue'
2
+ import { flip, offset, shift, useFloating } from '@floating-ui/vue'
3
+
4
+ export function useTooltip() {
5
+ const referenceEl = ref<HTMLElement | null>(null)
6
+ const floatingEl = useTemplateRef<HTMLElement>('floatingEl')
7
+ const visible = ref(false)
8
+ const activeText = ref<string | undefined>(undefined)
9
+
10
+ const { floatingStyles } = useFloating(referenceEl, floatingEl, {
11
+ placement: 'top-start',
12
+ strategy: 'fixed',
13
+ middleware: [offset(4), flip(), shift({ padding: 8 })],
14
+ })
15
+
16
+ function show(e: MouseEvent, text: string) {
17
+ referenceEl.value = e.currentTarget as HTMLElement
18
+ activeText.value = text
19
+ visible.value = true
20
+ }
21
+
22
+ function hide() {
23
+ visible.value = false
24
+ }
25
+
26
+ return { floatingStyles, visible, activeText, show, hide }
27
+ }
package/src/index.ts ADDED
@@ -0,0 +1,38 @@
1
+ import VPane from './components/VPane.vue'
2
+ import PFolder from './components/PFolder.vue'
3
+ import PLabel from './components/PLabel.vue'
4
+ import PText from './components/PText.vue'
5
+ import PNumber from './components/PNumber.vue'
6
+ import PButton from './components/PButton.vue'
7
+ import PSeparator from './components/PSeparator.vue'
8
+ import PCheckbox from './components/PCheckbox.vue'
9
+ import PSelect from './components/PSelect.vue'
10
+ import PMonitor from './components/PMonitor.vue'
11
+ import PMonitorMulti from './components/PMonitorMulti.vue'
12
+ import PSlider from './components/PSlider.vue'
13
+ import PTab from './components/PTab.vue'
14
+ import PColor from './components/PColor.vue'
15
+ import PGraph from './components/PGraph.vue'
16
+ import PPoint2d from './components/PPoint2d.vue'
17
+
18
+ export type { PaneConfig } from './composables/usePaneConfig'
19
+ export { usePaneConfig } from './composables/usePaneConfig'
20
+
21
+ export {
22
+ VPane,
23
+ PFolder,
24
+ PLabel,
25
+ PText,
26
+ PNumber,
27
+ PButton,
28
+ PSeparator,
29
+ PCheckbox,
30
+ PSelect,
31
+ PMonitor,
32
+ PMonitorMulti,
33
+ PSlider,
34
+ PTab,
35
+ PColor,
36
+ PGraph,
37
+ PPoint2d,
38
+ }
@@ -0,0 +1,12 @@
1
+ // Entry point for plugins
2
+
3
+ @forward './common/defs';
4
+
5
+ @forward './view/placeholder/button';
6
+ @forward './view/placeholder/container';
7
+ @forward './view/placeholder/folder';
8
+ @forward './view/placeholder/input';
9
+ @forward './view/placeholder/list';
10
+ @forward './view/placeholder/monitor';
11
+ @forward './view/placeholder/texts';
12
+ @forward './view/placeholder/theme';
@@ -0,0 +1,56 @@
1
+ @use 'sass:map';
2
+ @use 'sass:string';
3
+
4
+ $prefix: 'vp';
5
+
6
+ // Global state classes
7
+ $disabled: #{$prefix}--disabled;
8
+
9
+ // Common Sass variables
10
+ $fold-transition-duration: 0.2s;
11
+ $separator-width: 2px;
12
+ $slider-knob-size: 12px;
13
+ $z-index-picker: 1000;
14
+
15
+ // CSS variables — short names to reduce file size
16
+ $css-vars: (
17
+ 'base-bg': 'bs-bg',
18
+ 'base-border-radius': 'bs-br',
19
+ 'base-font': 'bs-ff',
20
+ 'base-shadow': 'bs-sh',
21
+ 'blade-border-radius': 'bld-br',
22
+ 'blade-h-padding': 'bld-hp',
23
+ 'blade-value-width': 'bld-vw',
24
+ 'button-bg': 'btn-bg',
25
+ 'button-bg-active': 'btn-bg-a',
26
+ 'button-bg-focus': 'btn-bg-f',
27
+ 'button-bg-hover': 'btn-bg-h',
28
+ 'button-fg': 'btn-fg',
29
+ 'container-bg': 'cnt-bg',
30
+ 'container-bg-active': 'cnt-bg-a',
31
+ 'container-bg-focus': 'cnt-bg-f',
32
+ 'container-bg-hover': 'cnt-bg-h',
33
+ 'container-fg': 'cnt-fg',
34
+ 'container-h-padding': 'cnt-hp',
35
+ 'container-unit-size': 'cnt-usz',
36
+ 'container-unit-spacing': 'cnt-usp',
37
+ 'container-v-padding': 'cnt-vp',
38
+ 'groove-fg': 'grv-fg',
39
+ 'input-bg': 'in-bg',
40
+ 'input-bg-active': 'in-bg-a',
41
+ 'input-bg-focus': 'in-bg-f',
42
+ 'input-bg-hover': 'in-bg-h',
43
+ 'input-fg': 'in-fg',
44
+ 'label-fg': 'lbl-fg',
45
+ 'monitor-bg': 'mo-bg',
46
+ 'monitor-fg': 'mo-fg',
47
+ );
48
+
49
+ @function cssVar($name) {
50
+ $short-name: map.get($css-vars, $name);
51
+ @if $short-name == null {
52
+ @error 'Short CSS variable for \'#{$name}\' not found.';
53
+ }
54
+ @return string.unquote('var(--' + $short-name + ')');
55
+ }
56
+
@@ -0,0 +1 @@
1
+ @use './view/views';
@@ -0,0 +1,12 @@
1
+ @use '../vp';
2
+
3
+ .vp-button {
4
+ &__btn {
5
+ @extend %vp-button;
6
+
7
+ width: 100%;
8
+ }
9
+ &__label {
10
+ text-align: center;
11
+ }
12
+ }
@@ -0,0 +1,54 @@
1
+ @use '../vp';
2
+
3
+ .vp-checkbox {
4
+ &__label {
5
+ display: block;
6
+ position: relative;
7
+ }
8
+ &__input {
9
+ left: 0;
10
+ opacity: 0;
11
+ position: absolute;
12
+ top: 0;
13
+ }
14
+ &__box {
15
+ background-color: vp.cssVar('input-bg');
16
+ border-radius: vp.cssVar('blade-border-radius');
17
+ cursor: pointer;
18
+ display: block;
19
+ height: vp.cssVar('container-unit-size');
20
+ position: relative;
21
+ width: vp.cssVar('container-unit-size');
22
+
23
+ svg {
24
+ display: block;
25
+ height: 16px;
26
+ inset: 0;
27
+ margin: auto;
28
+ opacity: 0;
29
+ position: absolute;
30
+ width: 16px;
31
+
32
+ path {
33
+ fill: none;
34
+ stroke: vp.cssVar('input-fg');
35
+ stroke-width: 2;
36
+ }
37
+ }
38
+ }
39
+ &__input:hover + &__box {
40
+ background-color: vp.cssVar('input-bg-hover');
41
+ }
42
+ &__input:focus + &__box {
43
+ background-color: vp.cssVar('input-bg-focus');
44
+ }
45
+ &__input:active + &__box {
46
+ background-color: vp.cssVar('input-bg-active');
47
+ }
48
+ &__input:checked + &__box svg {
49
+ opacity: 1;
50
+ }
51
+ &.#{vp.$disabled} &__box {
52
+ opacity: 0.5;
53
+ }
54
+ }
@@ -0,0 +1,57 @@
1
+ @use '../vp';
2
+
3
+ .vp-color {
4
+ position: relative;
5
+
6
+ &__header { display: flex; }
7
+ &__swatch { flex-grow: 0; flex-shrink: 0; width: vp.cssVar('container-unit-size'); }
8
+ &__text { flex: 1; margin-left: 4px; }
9
+
10
+ &__swatch-btn {
11
+ background-image: linear-gradient(45deg, #ccc 25%, transparent 25%),
12
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
13
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
14
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
15
+ background-position: 0 0, 0 4px, 4px -4px, -4px 0px;
16
+ background-size: 8px 8px;
17
+ border-radius: vp.cssVar('blade-border-radius');
18
+ cursor: pointer;
19
+ display: block;
20
+ height: vp.cssVar('container-unit-size');
21
+ overflow: hidden;
22
+ position: relative;
23
+ width: 100%;
24
+
25
+ &:focus::after {
26
+ border: rgba(white, 0.75) solid 2px;
27
+ border-radius: vp.cssVar('blade-border-radius');
28
+ box-sizing: border-box;
29
+ content: '';
30
+ display: block;
31
+ inset: 0;
32
+ position: absolute;
33
+ }
34
+
35
+ &__color { inset: 0; position: absolute; }
36
+ }
37
+
38
+ &__popup {
39
+ z-index: vp.$z-index-picker;
40
+
41
+ // vue-color CSS variable overrides — maps to our design tokens
42
+ --vc-body-bg: #{vp.cssVar('base-bg')};
43
+ --vc-picker-bg: rgba(255, 255, 255, 0.85);
44
+ --vc-input-bg: #{vp.cssVar('input-bg')};
45
+ --vc-input-text: #{vp.cssVar('container-fg')};
46
+ --vc-input-label: #{vp.cssVar('label-fg')};
47
+ --vc-input-border: rgba(255, 255, 255, 0.15);
48
+ --vc-chrome-toggle-btn-highlighted: #{vp.cssVar('input-bg-hover')};
49
+
50
+ .vc-chrome-picker {
51
+ box-sizing: border-box;
52
+ font-family: #{vp.cssVar('base-font')};
53
+ font-size: 11px;
54
+ width: 220px;
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,70 @@
1
+ @use '../vp';
2
+
3
+ .vp-folder {
4
+ position: relative;
5
+
6
+ // Title button
7
+ &__title {
8
+ @extend %vp-folder_title;
9
+ }
10
+ // Title text inside button
11
+ &__title-text {
12
+ padding-left: 4px;
13
+ }
14
+ // Expand/collapse chevron
15
+ &__chevron {
16
+ @extend %vp-folder_mark;
17
+ }
18
+ &__title:disabled &__chevron {
19
+ display: none;
20
+ }
21
+ &#{&}--expanded > &__title > &__chevron {
22
+ @extend %vp-folder_mark-expanded;
23
+ }
24
+ // Children container
25
+ &__content {
26
+ @extend %vp-folder_container;
27
+ @extend %vp-container_children;
28
+ @extend %vp-container_subcontainers;
29
+
30
+ padding-left: 4px;
31
+ }
32
+ &#{&}--expanded > &__content {
33
+ @extend %vp-folder_container-expanded;
34
+ }
35
+ &#{&}--complete:not(#{&}--expanded) > &__content {
36
+ @extend %vp-folder_container-shrinkedCompletely;
37
+ }
38
+ // Indent line
39
+ &__indent {
40
+ bottom: 0;
41
+ color: vp.cssVar('container-bg');
42
+ left: 0;
43
+ overflow: hidden;
44
+ position: absolute;
45
+ top: calc(#{vp.cssVar('container-unit-size')} + 4px);
46
+ width: max(vp.cssVar('base-border-radius'), 4px);
47
+
48
+ &::before {
49
+ background-color: currentColor;
50
+ bottom: 0;
51
+ content: '';
52
+ left: 0;
53
+ position: absolute;
54
+ top: 0;
55
+ width: 4px;
56
+ }
57
+ }
58
+ &__title:hover + &__indent {
59
+ color: vp.cssVar('container-bg-hover');
60
+ }
61
+ &__title:focus + &__indent {
62
+ color: vp.cssVar('container-bg-focus');
63
+ }
64
+ &__title:active + &__indent {
65
+ color: vp.cssVar('container-bg-active');
66
+ }
67
+ &.#{vp.$disabled} > &__indent {
68
+ opacity: 0.5;
69
+ }
70
+ }
@@ -0,0 +1,11 @@
1
+ @use '../vp';
2
+
3
+ .vp-graph {
4
+ position: relative;
5
+ &__svg {
6
+ @extend %vp-monitor;
7
+ display: block; height: calc(vp.cssVar('container-unit-size') * 3);
8
+ polyline { fill: none; stroke: vp.cssVar('monitor-fg'); stroke-linejoin: round; }
9
+ }
10
+ &.vp--disabled &__svg { opacity: 0.5; }
11
+ }
@@ -0,0 +1,37 @@
1
+ @use '../vp';
2
+
3
+ .vp-label {
4
+ align-items: center;
5
+ display: flex;
6
+ line-height: 1.3;
7
+ padding-left: vp.cssVar('container-h-padding');
8
+ padding-right: vp.cssVar('container-h-padding');
9
+
10
+ &--no-label {
11
+ display: block;
12
+ }
13
+
14
+ &__text {
15
+ color: vp.cssVar('label-fg');
16
+ flex: 1;
17
+ hyphens: auto;
18
+ overflow: hidden;
19
+ padding-left: 4px;
20
+ padding-right: 16px;
21
+ }
22
+ &.#{vp.$disabled} &__text {
23
+ opacity: 0.5;
24
+ }
25
+ &--no-label &__text {
26
+ display: none;
27
+ }
28
+ &__value {
29
+ align-self: flex-start;
30
+ flex-grow: 0;
31
+ flex-shrink: 0;
32
+ width: vp.cssVar('blade-value-width');
33
+ }
34
+ &--no-label &__value {
35
+ width: 100%;
36
+ }
37
+ }
@@ -0,0 +1,17 @@
1
+ @use '../vp';
2
+
3
+ .vp-select {
4
+ @extend %vp-list;
5
+
6
+ &__input {
7
+ @extend %vp-list_select;
8
+
9
+ padding: 0 (16px + 2px * 2) 0 vp.cssVar('blade-h-padding');
10
+ width: 100%;
11
+ }
12
+ &__arrow {
13
+ @extend %vp-list_arrow;
14
+
15
+ color: vp.cssVar('button-fg');
16
+ }
17
+ }
@@ -0,0 +1,13 @@
1
+ @use '../vp';
2
+
3
+ .vp-monitor {
4
+ &__value {
5
+ @extend %vp-monitor;
6
+
7
+ padding-left: vp.cssVar('blade-h-padding');
8
+ padding-right: vp.cssVar('blade-h-padding');
9
+ }
10
+ &.#{vp.$disabled} &__value {
11
+ opacity: 0.5;
12
+ }
13
+ }