@bagelink/vue 0.0.1020 → 0.0.1023

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "0.0.1020",
4
+ "version": "0.0.1023",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -23,6 +23,7 @@ const props = withDefaults(
23
23
  href?: string
24
24
  round?: boolean
25
25
  is?: string
26
+ ripple?: boolean
26
27
  onClick?: (e: MouseEvent) => void
27
28
  }>(),
28
29
  {
@@ -34,7 +35,8 @@ const props = withDefaults(
34
35
  role: 'button',
35
36
  is: 'button',
36
37
  border: false,
37
- outline: false
38
+ outline: false,
39
+ ripple: true,
38
40
  },
39
41
  )
40
42
 
@@ -54,13 +56,13 @@ const bind = $computed(() => {
54
56
  }
55
57
  return obj
56
58
  })
57
- const slots: SetupContext["slots"] = useSlots()
59
+ const slots: SetupContext['slots'] = useSlots()
58
60
  </script>
59
61
 
60
62
  <template>
61
63
  <component
62
64
  :is="isComponent"
63
- v-ripple v-bind="bind" :disabled="disabled"
65
+ v-ripple="ripple" v-bind="bind" :disabled="disabled"
64
66
  class="bgl_btn"
65
67
  :class="{
66
68
  'bgl_btn-icon': icon && !slots.default && !value,
@@ -8,7 +8,6 @@ import type {
8
8
  Field,
9
9
  } from '@bagelink/vue'
10
10
  import { BglForm, Btn } from '@bagelink/vue'
11
- import Card from '../Card.vue'
12
11
 
13
12
  const props = withDefaults(
14
13
  defineProps<{
@@ -76,7 +75,7 @@ function addItem() {
76
75
  <p class="label mb-05">
77
76
  {{ label }}
78
77
  </p>
79
- <div class="ps-05 border-start">
78
+ <div class="-ms-05 ps-05 border-start">
80
79
  <div v-for="(_, i) in data" :key="i" outline thin class="mb-05 itemBox transition p-05">
81
80
  <BglForm v-if="schema" v-model="data[i]" :schema="schema" @update:model-value="emitValue" />
82
81
  <Btn
@@ -1,110 +1,175 @@
1
- <script lang="ts" setup>
1
+ <script setup lang="ts">
2
2
  import { watch } from 'vue'
3
3
 
4
- interface RangeInputProps {
5
- min?: number
6
- max?: number
4
+ interface props {
5
+ min: number
6
+ max: number
7
+ modelValue: number | [number, number]
7
8
  step?: number
9
+ required?: boolean
10
+ label?: string
8
11
  disabled?: boolean
9
12
  id?: string
10
- name?: string
11
- required?: boolean
12
- thickness?: string
13
+ rtl?: boolean
13
14
  }
14
- const { min, max, step, thickness = '8px' } = defineProps<RangeInputProps>()
15
- const val = defineModel<number>({ default: 0 })
16
- const range = $ref<HTMLInputElement>()
17
-
18
- const direction = $computed(() => {
19
- if (!range) return 'ltr'
20
- const parent = range.parentElement
21
- return getComputedStyle(parent!).direction
22
- })
23
15
 
24
- const background = $computed(() => {
25
- const minVal = min ?? 0
26
- const maxVal = max ?? 100
27
- const percentage = ((val.value - minVal) / (maxVal - minVal)) * 100
16
+ const { min = 0, max = 100, step = 1, modelValue, label, disabled, id, rtl } = defineProps<props>()
28
17
 
29
- if (direction === 'rtl') {
30
- return `linear-gradient(to left, var(--bgl-primary) ${percentage}%, var(--input-bg) ${percentage}%)`
31
- }
32
- return `linear-gradient(to right, var(--bgl-primary) ${percentage}%, var(--input-bg) ${percentage}%)`
33
- })
18
+ const emit = defineEmits(['update:modelValue'])
19
+
20
+ const isRange = $computed(() => Array.isArray(modelValue))
21
+
22
+ let from = $ref<number>(min)
23
+ let to = $ref<number>(max)
24
+
25
+ const validFrom = $computed(() => Math.min(Math.max(from, min), to)) as number
26
+ const validTo = $computed(() => Math.max(Math.min(to, max), from)) as number
34
27
 
35
- watch(() => val.value, (newValue: number) => {
36
- if (min !== undefined && newValue < min) val.value = min
37
- if (max !== undefined && newValue > max) val.value = max
28
+ function emitValue() {
29
+ emit('update:modelValue', isRange ? [validFrom, validTo] : validFrom)
30
+ }
31
+
32
+ watch(() => validFrom, (newVal) => {
33
+ if (from !== newVal) from = newVal
34
+ })
35
+ watch(() => validTo, (newVal) => {
36
+ if (to !== newVal) to = newVal
38
37
  })
39
38
 
40
- const height = $computed(() => {
41
- return Number.isNaN(Number(thickness)) ? thickness : `${thickness}px`
39
+ const fromPercentage = $computed(() => ((validFrom - min) / (max - min)) * 100)
40
+ const toPercentage = $computed(() => ((validTo - min) / (max - min)) * 100)
41
+
42
+ const rangeStyle = $computed(() => {
43
+ const width = ((validTo - validFrom) / (max - min)) * 100
44
+ if (rtl || isRange) return { left: `${fromPercentage}%`, width: `${width}%` }
45
+ return { right: `${width}%`, width: `${fromPercentage}%` }
42
46
  })
43
47
  </script>
44
48
 
45
49
  <template>
46
- <div class="flex gap-1 align-center range-slide" :class="{ disabled }">
47
- <p v-if="min !== undefined">
48
- {{ min }}
49
- </p>
50
- <input
51
- :id
52
- ref="range"
53
- v-model="val"
54
- :disabled="disabled"
55
- :style="{ background, height }"
56
- :max :min
57
- :step
58
- :required
59
- type="range"
60
- :name
61
- >
62
- <p v-if="max !== undefined">
63
- {{ max }}
50
+ <div>
51
+ <label class="label">{{ label }}</label>
52
+ <div class="range-slider relative w-100">
53
+ <input
54
+ :id="id"
55
+ v-model="from"
56
+ class="from"
57
+ type="range"
58
+ :min="min"
59
+ :max="max"
60
+ :step="step"
61
+ :required="required"
62
+ :disabled="disabled"
63
+ aria-label="Minimum value"
64
+ @change="emitValue"
65
+ >
66
+ <input
67
+ v-if="isRange"
68
+ v-model="to"
69
+ class="to"
70
+ type="range"
71
+ :min="min"
72
+ :max="max"
73
+ :step="step"
74
+ :required="required"
75
+ :disabled="disabled"
76
+ aria-label="Maximum value"
77
+ @change="emitValue"
78
+ >
79
+ <div class="track absolute pointer-events-none overflow-hidden round">
80
+ <div
81
+ class="active-range absolute h-100 pointer-events-none bg-primary"
82
+ :style="rangeStyle"
83
+ />
84
+ </div>
85
+ <p
86
+ v-if="from !== min"
87
+ class="txt-center txt-12 range-slider-position-txt absolute line-height-1 opacity-0 "
88
+ :style="{ marginInlineStart: `calc(${fromPercentage}% - 4px)` }"
89
+ >
90
+ <span>
91
+ {{ from }}
92
+ </span>
93
+ </p>
94
+ <p
95
+ v-if="isRange && to !== max"
96
+ class="txt-center txt-12 range-slider-position-txt opacity-0 line-height-1 absolute"
97
+ :style="{ marginInlineStart: `calc(${toPercentage}% - 12px)` }"
98
+ >
99
+ <span>
100
+ {{ to }}
101
+ </span>
102
+ </p>
103
+ </div>
104
+ <p class="txt-center txt-14 range-slider-txt flex space-between opacity-4 mx-05">
105
+ <span>
106
+ {{ min }}
107
+ </span>
108
+ <span>
109
+ {{ max }}
110
+ </span>
64
111
  </p>
65
112
  </div>
66
113
  </template>
67
114
 
68
115
  <style scoped>
69
- .range-slide input {
70
- -webkit-appearance: none;
71
- width: 100%;
72
- border-radius: 5px;
73
- outline: none;
74
- transition: background 0.3s ease;
116
+ .range-slider-position-txt{
117
+ top: calc(var(--bgl-range-thumb-size) / 2 ) ;
118
+ transition: transform 0.1s, opacity 0.5s;
119
+ transform: scale(0.5);
120
+ }
121
+ .range-slider:hover .range-slider-position-txt{
122
+ opacity: 1;
123
+ transform: scale(1);
124
+ }
125
+ .range-slider {
126
+ height: var(--bgl-range-track-size);
127
+ display: flex;
128
+ align-items: center;
129
+ margin-top: calc(var(--bgl-range-thumb-size) / 2 + 0.5rem) ;
130
+ }
131
+ .range-slider-txt{
132
+ margin-top: calc(var(--bgl-range-thumb-size) / 2) !important;
75
133
  }
76
134
 
77
- .range-slide input::-webkit-slider-thumb {
78
- -webkit-appearance: none;
135
+ input[type="range"] {
136
+ position: absolute;
137
+ width: 100%;
138
+ height: 100%;
139
+ height: var(--bgl-range-thumb-size);
140
+ background: transparent;
141
+ pointer-events: none;
79
142
  appearance: none;
80
- /* margin-top: calc(-1 * var(--thickness, 8px) / 2); */
81
- margin-top: 0;
82
- width: 16px;
83
- height: 16px;
84
- background: var(--bgl-primary);
85
- border: 1px solid var(--input-bg);
86
- border-radius: 50%;
87
- cursor: pointer;
143
+ margin: 0;
88
144
  }
89
145
 
90
- .range-slide input::-moz-range-thumb {
91
- width: 16px;
92
- height: 16px;
93
- margin-top: calc(-1 * var(--thickness, 8px) / 2);
94
- background: var(--bgl-primary);
95
- border: 1px solid var(--input-bg);
146
+ input[type="range"]::-webkit-slider-thumb {
147
+ pointer-events: all;
148
+ appearance: none;
149
+ width: var(--bgl-range-thumb-size);
150
+ height: var(--bgl-range-thumb-size);
151
+ background: var(--bgl-white);
96
152
  border-radius: 50%;
153
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
154
+ position: relative;
155
+ z-index: 2;
97
156
  cursor: pointer;
157
+ transition: var(--bgl-transition);
158
+ }
159
+ input[type="range"]::-webkit-slider-thumb:hover {
160
+ box-shadow: 0 0 0 calc(var(--bgl-range-thumb-size) / 2) var(--bgl-primary-tint);
161
+ filter: brightness(90%);
98
162
  }
99
163
 
100
- .range-slide.disabled input[type='range']::-webkit-slider-thumb {
101
- display: none;
164
+ input[type="range"]:focus::-webkit-slider-thumb {
165
+ outline: none;
166
+ box-shadow: 0 0 0 calc(var(--bgl-range-thumb-size) / 2.2) var(--bgl-primary-tint);
102
167
  }
103
168
 
104
- .range-slide input::-webkit-slider-runnable-track,
105
- .range-slide input::-moz-range-track {
106
- width: 100%;
107
- background: transparent;
108
- border-radius: 5px;
169
+ .track {
170
+ height: var(--bgl-range-track-height);
171
+ background: var(--bgl-bg);
172
+ margin-inline-start: calc(var(--bgl-range-thumb-size) / 2);
173
+ width: calc(100% - var(--bgl-range-thumb-size));
109
174
  }
110
175
  </style>
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { Icon, type MaterialIcons } from '@bagelink/vue'
2
+ import type { MaterialIcons } from '@bagelink/vue'
3
3
  import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
4
4
  import { useTabs } from './tabsManager'
5
5
 
@@ -80,17 +80,19 @@ onBeforeUnmount(() => {
80
80
  ref="tabsWrap" class="grid auto-flow-columns relative fit-content bgl_tabs_wrap overflow-hidden"
81
81
  :class="{ 'bgl_flat-tabs': flat, 'bgl_vertical-tabs': vertical }"
82
82
  >
83
- <button
84
- v-for="(tab, i) in props.tabs"
85
- :key="i"
86
- type="button"
87
- :class="{ active: isActive(tab) }"
88
- class="bgl_tab relative z-1"
89
- @click="selectTab(tab)"
90
- >
91
- <Icon v-if="typeof tab !== 'string' && tab.icon" :icon="tab.icon" />
92
- {{ tabLabel(tab) }}
93
- </button>
83
+ <slot name="tabs" v-bind="{ selectTab, isActive, tabLabel, tabs }">
84
+ <button
85
+ v-for="(tab, i) in props.tabs"
86
+ :key="i"
87
+ type="button"
88
+ :class="{ active: isActive(tab) }"
89
+ class="bgl_tab relative z-1"
90
+ @click="selectTab(tab)"
91
+ >
92
+ <Icon v-if="typeof tab !== 'string' && tab.icon" :icon="tab.icon" />
93
+ {{ tabLabel(tab) }}
94
+ </button>
95
+ </slot>
94
96
  </div>
95
97
  </template>
96
98
 
@@ -497,6 +497,10 @@
497
497
  box-shadow: 0 0 20px 0 var(--bgl-shadow) !important;
498
498
  }
499
499
 
500
+ .shadow-none {
501
+ box-shadow: none !important;
502
+ }
503
+
500
504
  .shadow-30 {
501
505
  box-shadow: 0 0 30px 0 var(--bgl-shadow) !important;
502
506
  }
@@ -1151,6 +1155,10 @@
1151
1155
  box-shadow: 0 0 20px 0 var(--bgl-shadow) !important;
1152
1156
  }
1153
1157
 
1158
+ .m_shadow-none {
1159
+ box-shadow: none !important;
1160
+ }
1161
+
1154
1162
  .m_shadow-30 {
1155
1163
  box-shadow: 0 0 30px 0 var(--bgl-shadow) !important;
1156
1164
  }