Website Structure
This commit is contained in:
parent
62812f2090
commit
71f0676a62
22365 changed files with 4265753 additions and 791 deletions
50
Frontend-Learner/node_modules/quasar/src/Brand.json
generated
vendored
Normal file
50
Frontend-Learner/node_modules/quasar/src/Brand.json
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/style/color-palette"
|
||||
},
|
||||
|
||||
"internal": true,
|
||||
|
||||
"quasarConfOptions": {
|
||||
"propName": "brand",
|
||||
"type": "Object",
|
||||
"definition": {
|
||||
"primary": {
|
||||
"type": "String",
|
||||
"desc": "Main color of your app"
|
||||
},
|
||||
"secondary": {
|
||||
"type": "String",
|
||||
"desc": "Secondary color of your app"
|
||||
},
|
||||
"accent": {
|
||||
"type": "String",
|
||||
"desc": "Accent color of your app"
|
||||
},
|
||||
"dark": {
|
||||
"type": "String",
|
||||
"desc": "Dark color of your app"
|
||||
},
|
||||
"positive": {
|
||||
"type": "String",
|
||||
"desc": "Positive color of your app"
|
||||
},
|
||||
"negative": {
|
||||
"type": "String",
|
||||
"desc": "Negative color of your app"
|
||||
},
|
||||
"info": {
|
||||
"type": "String",
|
||||
"desc": "Info color of your app"
|
||||
},
|
||||
"warning": {
|
||||
"type": "String",
|
||||
"desc": "Warning color of your app"
|
||||
},
|
||||
"...customColors": {
|
||||
"type": "String",
|
||||
"desc": "Custom colors of your app, if any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
264
Frontend-Learner/node_modules/quasar/src/api.extends.json
generated
vendored
Normal file
264
Frontend-Learner/node_modules/quasar/src/api.extends.json
generated
vendored
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
{
|
||||
"props": {
|
||||
"readonly": {
|
||||
"type": "Boolean",
|
||||
"desc": "Put component in readonly mode",
|
||||
"category": "state"
|
||||
},
|
||||
|
||||
"disable": {
|
||||
"type": "Boolean",
|
||||
"desc": "Put component in disabled mode",
|
||||
"category": "state"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"type": "String",
|
||||
"tsType": "NamedColor",
|
||||
"desc": "Color name for component from the Quasar Color Palette",
|
||||
"examples": [ "'primary'", "'teal'", "'teal-10'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"text-color": {
|
||||
"type": "String",
|
||||
"tsType": "NamedColor",
|
||||
"desc": "Overrides text color (if needed); Color name from the Quasar Color Palette",
|
||||
"examples": [ "'primary'", "'teal'", "'teal-10'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"dense": {
|
||||
"type": "Boolean",
|
||||
"desc": "Dense mode; occupies less space",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"size": {
|
||||
"type": "String",
|
||||
"desc": "Size in CSS units, including unit name",
|
||||
"examples": [ "'16px'", "'2rem'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"dark": {
|
||||
"type": [ "Boolean", "null" ],
|
||||
"default": "null",
|
||||
"desc": "Notify the component that the background is a dark color",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"icon": {
|
||||
"type": "String",
|
||||
"desc": "Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)",
|
||||
"examples": [
|
||||
"'map'",
|
||||
"'ion-add'",
|
||||
"'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'",
|
||||
"'img:path/to/some_image.png'"
|
||||
],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"flat": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a 'flat' design (no default shadow)",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"bordered": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a default border to the component",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"square": {
|
||||
"type": "Boolean",
|
||||
"desc": "Removes border-radius so borders are squared",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"rounded": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a small standard border-radius for a squared shape of the component",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"tabindex": {
|
||||
"type": [ "Number", "String" ],
|
||||
"desc": "Tabindex HTML attribute value",
|
||||
"examples": [ "100", "'0'" ],
|
||||
"category": "general"
|
||||
},
|
||||
|
||||
"transition": {
|
||||
"type": "String",
|
||||
"desc": "One of Quasar's embedded transitions",
|
||||
"examples": [ "'fade'", "'slide-down'" ],
|
||||
"category": "transition"
|
||||
},
|
||||
|
||||
"animation-speed": {
|
||||
"type": [ "String", "Number" ],
|
||||
"desc": "Animation speed (in milliseconds, without unit)",
|
||||
"examples": [ "500", "'1200'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"model-value": {
|
||||
"desc": "Model of the component; Either use this property (along with a listener for 'update:model-value' event) OR use v-model directive",
|
||||
"required": true,
|
||||
"syncable": true,
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"html": {
|
||||
"type": "Boolean",
|
||||
"desc": "Force use of textContent instead of innerHTML to render text; Use it when the text might be unsafe (from user input)",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"tag": {
|
||||
"type": "String",
|
||||
"desc": "HTML tag to use",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"scroll-target": {
|
||||
"type": [ "Element", "String" ],
|
||||
"desc": "CSS selector or DOM element to be used as a custom scroll container instead of the auto detected one",
|
||||
"examples": [
|
||||
".scroll-target-class",
|
||||
"#scroll-target-id",
|
||||
"$refs.scrollTarget",
|
||||
"document.body"
|
||||
],
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"ripple": {
|
||||
"type": [ "Boolean", "Object" ],
|
||||
"desc": "Configure material ripple (disable it by setting it to 'false' or supply a config object)",
|
||||
"default": "true",
|
||||
"examples": [ "false", "{ early: true, center: true, color: 'teal', keyCodes: [] }" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"evt": {
|
||||
"type": "Event",
|
||||
"desc": "JS event object"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Default slot in the devland unslotted content of the component"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"update:model-value": {
|
||||
"desc": "Emitted when the component needs to change the model; Is also used by v-model",
|
||||
"params": {
|
||||
"value": {
|
||||
"type": "Any",
|
||||
"desc": "New model value",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"show": {
|
||||
"desc": "Emitted after component has triggered show()",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"before-show": {
|
||||
"desc": "Emitted when component triggers show() but before it finishes doing it",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"after-show": {
|
||||
"desc": "Emitted when component show animation is finished"
|
||||
},
|
||||
|
||||
"hide": {
|
||||
"desc": "Emitted after component has triggered hide()",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"before-hide": {
|
||||
"desc": "Emitted when component triggers hide() but before it finishes doing it",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"after-hide": {
|
||||
"desc": "Emitted when component hide animation is finished"
|
||||
},
|
||||
|
||||
"click": {
|
||||
"desc": "Emitted when user clicks/taps on the component",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"show": {
|
||||
"desc": "Triggers component to show",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": false
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"hide": {
|
||||
"desc": "Triggers component to hide",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": false
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"toggle": {
|
||||
"desc": "Triggers component to toggle between show/hide",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": false
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Frontend-Learner/node_modules/quasar/src/components.js
generated
vendored
Normal file
79
Frontend-Learner/node_modules/quasar/src/components.js
generated
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
export * from './components/ajax-bar/index.js'
|
||||
export * from './components/avatar/index.js'
|
||||
export * from './components/badge/index.js'
|
||||
export * from './components/banner/index.js'
|
||||
export * from './components/bar/index.js'
|
||||
export * from './components/breadcrumbs/index.js'
|
||||
export * from './components/btn/index.js'
|
||||
export * from './components/btn-dropdown/index.js'
|
||||
export * from './components/btn-group/index.js'
|
||||
export * from './components/btn-toggle/index.js'
|
||||
export * from './components/card/index.js'
|
||||
export * from './components/carousel/index.js'
|
||||
export * from './components/chat/index.js'
|
||||
export * from './components/checkbox/index.js'
|
||||
export * from './components/chip/index.js'
|
||||
export * from './components/circular-progress/index.js'
|
||||
export * from './components/color/index.js'
|
||||
export * from './components/date/index.js'
|
||||
export * from './components/dialog/index.js'
|
||||
export * from './components/drawer/index.js'
|
||||
export * from './components/editor/index.js'
|
||||
export * from './components/expansion-item/index.js'
|
||||
export * from './components/fab/index.js'
|
||||
export * from './components/field/index.js'
|
||||
export * from './components/file/index.js'
|
||||
export * from './components/footer/index.js'
|
||||
export * from './components/form/index.js'
|
||||
export * from './components/header/index.js'
|
||||
export * from './components/icon/index.js'
|
||||
export * from './components/img/index.js'
|
||||
export * from './components/infinite-scroll/index.js'
|
||||
export * from './components/inner-loading/index.js'
|
||||
export * from './components/input/index.js'
|
||||
export * from './components/intersection/index.js'
|
||||
export * from './components/item/index.js'
|
||||
export * from './components/knob/index.js'
|
||||
export * from './components/layout/index.js'
|
||||
export * from './components/markup-table/index.js'
|
||||
export * from './components/menu/index.js'
|
||||
export * from './components/no-ssr/index.js'
|
||||
export * from './components/option-group/index.js'
|
||||
export * from './components/page/index.js'
|
||||
export * from './components/page-scroller/index.js'
|
||||
export * from './components/page-sticky/index.js'
|
||||
export * from './components/pagination/index.js'
|
||||
export * from './components/parallax/index.js'
|
||||
export * from './components/popup-edit/index.js'
|
||||
export * from './components/popup-proxy/index.js'
|
||||
export * from './components/linear-progress/index.js'
|
||||
export * from './components/pull-to-refresh/index.js'
|
||||
export * from './components/radio/index.js'
|
||||
export * from './components/range/index.js'
|
||||
export * from './components/rating/index.js'
|
||||
export * from './components/resize-observer/index.js'
|
||||
export * from './components/responsive/index.js'
|
||||
export * from './components/scroll-area/index.js'
|
||||
export * from './components/scroll-observer/index.js'
|
||||
export * from './components/select/index.js'
|
||||
export * from './components/separator/index.js'
|
||||
export * from './components/skeleton/index.js'
|
||||
export * from './components/slide-item/index.js'
|
||||
export * from './components/slide-transition/index.js'
|
||||
export * from './components/slider/index.js'
|
||||
export * from './components/space/index.js'
|
||||
export * from './components/spinner/index.js'
|
||||
export * from './components/splitter/index.js'
|
||||
export * from './components/stepper/index.js'
|
||||
export * from './components/tab-panels/index.js'
|
||||
export * from './components/table/index.js'
|
||||
export * from './components/tabs/index.js'
|
||||
export * from './components/time/index.js'
|
||||
export * from './components/timeline/index.js'
|
||||
export * from './components/toggle/index.js'
|
||||
export * from './components/toolbar/index.js'
|
||||
export * from './components/tooltip/index.js'
|
||||
export * from './components/tree/index.js'
|
||||
export * from './components/uploader/index.js'
|
||||
export * from './components/video/index.js'
|
||||
export * from './components/virtual-scroll/index.js'
|
||||
288
Frontend-Learner/node_modules/quasar/src/components/ajax-bar/QAjaxBar.js
generated
vendored
Normal file
288
Frontend-Learner/node_modules/quasar/src/components/ajax-bar/QAjaxBar.js
generated
vendored
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
import { h, ref, computed, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { between } from '../../utils/format/format.js'
|
||||
|
||||
const
|
||||
xhr = __QUASAR_SSR_SERVER__ ? null : XMLHttpRequest,
|
||||
open = __QUASAR_SSR_SERVER__ ? null : xhr.prototype.open,
|
||||
positionValues = [ 'top', 'right', 'bottom', 'left' ]
|
||||
|
||||
let stack = []
|
||||
let highjackCount = 0
|
||||
|
||||
function translate ({ p, pos, active, horiz, reverse, dir }) {
|
||||
let x = 1, y = 1
|
||||
|
||||
if (horiz === true) {
|
||||
if (reverse === true) { x = -1 }
|
||||
if (pos === 'bottom') { y = -1 }
|
||||
return { transform: `translate3d(${ x * (p - 100) }%,${ active ? 0 : y * -200 }%,0)` }
|
||||
}
|
||||
|
||||
if (reverse === true) { y = -1 }
|
||||
if (pos === 'right') { x = -1 }
|
||||
return { transform: `translate3d(${ active ? 0 : dir * x * -200 }%,${ y * (p - 100) }%,0)` }
|
||||
}
|
||||
|
||||
function inc (p, amount) {
|
||||
if (typeof amount !== 'number') {
|
||||
if (p < 25) {
|
||||
amount = Math.random() * 3 + 3
|
||||
}
|
||||
else if (p < 65) {
|
||||
amount = Math.random() * 3
|
||||
}
|
||||
else if (p < 85) {
|
||||
amount = Math.random() * 2
|
||||
}
|
||||
else if (p < 99) {
|
||||
amount = 0.6
|
||||
}
|
||||
else {
|
||||
amount = 0
|
||||
}
|
||||
}
|
||||
return between(p + amount, 0, 100)
|
||||
}
|
||||
|
||||
function highjackAjax (stackEntry) {
|
||||
highjackCount++
|
||||
|
||||
stack.push(stackEntry)
|
||||
|
||||
if (highjackCount > 1) return
|
||||
|
||||
xhr.prototype.open = function (_, url) {
|
||||
const stopStack = []
|
||||
|
||||
const loadStart = () => {
|
||||
stack.forEach(entry => {
|
||||
if (
|
||||
entry.hijackFilter.value === null
|
||||
|| (entry.hijackFilter.value(url) === true)
|
||||
) {
|
||||
entry.start()
|
||||
stopStack.push(entry.stop)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const loadEnd = () => {
|
||||
stopStack.forEach(stop => { stop() })
|
||||
}
|
||||
|
||||
this.addEventListener('loadstart', loadStart, { once: true })
|
||||
this.addEventListener('loadend', loadEnd, { once: true })
|
||||
|
||||
open.apply(this, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
function restoreAjax (start) {
|
||||
stack = stack.filter(entry => entry.start !== start)
|
||||
|
||||
highjackCount = Math.max(0, highjackCount - 1)
|
||||
if (highjackCount === 0) {
|
||||
xhr.prototype.open = open
|
||||
}
|
||||
}
|
||||
|
||||
export default createComponent({
|
||||
name: 'QAjaxBar',
|
||||
|
||||
props: {
|
||||
position: {
|
||||
type: String,
|
||||
default: 'top',
|
||||
validator: val => positionValues.includes(val)
|
||||
},
|
||||
|
||||
size: {
|
||||
type: String,
|
||||
default: '2px'
|
||||
},
|
||||
|
||||
color: String,
|
||||
skipHijack: Boolean,
|
||||
reverse: Boolean,
|
||||
|
||||
hijackFilter: Function
|
||||
},
|
||||
|
||||
emits: [ 'start', 'stop' ],
|
||||
|
||||
setup (props, { emit }) {
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const progress = ref(0)
|
||||
const onScreen = ref(false)
|
||||
const animate = ref(true)
|
||||
|
||||
let sessions = 0, timer = null, speed
|
||||
|
||||
const classes = computed(() =>
|
||||
`q-loading-bar q-loading-bar--${ props.position }`
|
||||
+ (props.color !== void 0 ? ` bg-${ props.color }` : '')
|
||||
+ (animate.value === true ? '' : ' no-transition')
|
||||
)
|
||||
|
||||
const horizontal = computed(() => props.position === 'top' || props.position === 'bottom')
|
||||
const sizeProp = computed(() => (horizontal.value === true ? 'height' : 'width'))
|
||||
|
||||
const style = computed(() => {
|
||||
const active = onScreen.value
|
||||
|
||||
const obj = translate({
|
||||
p: progress.value,
|
||||
pos: props.position,
|
||||
active,
|
||||
horiz: horizontal.value,
|
||||
reverse: proxy.$q.lang.rtl === true && [ 'top', 'bottom' ].includes(props.position)
|
||||
? props.reverse === false
|
||||
: props.reverse,
|
||||
dir: proxy.$q.lang.rtl === true ? -1 : 1
|
||||
})
|
||||
|
||||
obj[ sizeProp.value ] = props.size
|
||||
obj.opacity = active ? 1 : 0
|
||||
|
||||
return obj
|
||||
})
|
||||
|
||||
const attributes = computed(() => (
|
||||
onScreen.value === true
|
||||
? {
|
||||
role: 'progressbar',
|
||||
'aria-valuemin': 0,
|
||||
'aria-valuemax': 100,
|
||||
'aria-valuenow': progress.value
|
||||
}
|
||||
: { 'aria-hidden': 'true' }
|
||||
))
|
||||
|
||||
function start (newSpeed = 300) {
|
||||
const oldSpeed = speed
|
||||
speed = Math.max(0, newSpeed) || 0
|
||||
|
||||
sessions++
|
||||
|
||||
if (sessions > 1) {
|
||||
if (oldSpeed === 0 && newSpeed > 0) {
|
||||
planNextStep()
|
||||
}
|
||||
else if (timer !== null && oldSpeed > 0 && newSpeed <= 0) {
|
||||
clearTimeout(timer)
|
||||
timer = null
|
||||
}
|
||||
|
||||
return sessions
|
||||
}
|
||||
|
||||
timer !== null && clearTimeout(timer)
|
||||
emit('start')
|
||||
|
||||
progress.value = 0
|
||||
|
||||
/**
|
||||
* We're trying to avoid side effects if start() is called inside a watchEffect()
|
||||
* so we're accessing the _value property directly (under the covers implementation detail of ref())
|
||||
*
|
||||
* Otherwise, any refs() accessed here would be marked as deps for the watchEffect()
|
||||
* -- and we are changing them below, which would cause an infinite loop
|
||||
*/
|
||||
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
animate.value = true
|
||||
newSpeed > 0 && planNextStep()
|
||||
// eslint-disable-next-line vue/no-ref-as-operand
|
||||
}, onScreen._value === true ? 500 : 1)
|
||||
|
||||
// eslint-disable-next-line vue/no-ref-as-operand
|
||||
if (onScreen._value !== true) {
|
||||
onScreen.value = true
|
||||
animate.value = false
|
||||
}
|
||||
|
||||
return sessions
|
||||
}
|
||||
|
||||
function increment (amount) {
|
||||
if (sessions > 0) {
|
||||
progress.value = inc(progress.value, amount)
|
||||
}
|
||||
|
||||
return sessions
|
||||
}
|
||||
|
||||
function stop () {
|
||||
sessions = Math.max(0, sessions - 1)
|
||||
if (sessions > 0) {
|
||||
return sessions
|
||||
}
|
||||
|
||||
if (timer !== null) {
|
||||
clearTimeout(timer)
|
||||
timer = null
|
||||
}
|
||||
|
||||
emit('stop')
|
||||
|
||||
const end = () => {
|
||||
animate.value = true
|
||||
progress.value = 100
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
onScreen.value = false
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
if (progress.value === 0) {
|
||||
timer = setTimeout(end, 1)
|
||||
}
|
||||
else {
|
||||
end()
|
||||
}
|
||||
|
||||
return sessions
|
||||
}
|
||||
|
||||
function planNextStep () {
|
||||
if (progress.value < 100) {
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
increment()
|
||||
planNextStep()
|
||||
}, speed)
|
||||
}
|
||||
}
|
||||
|
||||
let hijacked
|
||||
|
||||
onMounted(() => {
|
||||
if (props.skipHijack !== true) {
|
||||
hijacked = true
|
||||
highjackAjax({
|
||||
start,
|
||||
stop,
|
||||
hijackFilter: computed(() => props.hijackFilter || null)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
timer !== null && clearTimeout(timer)
|
||||
hijacked === true && restoreAjax(start)
|
||||
})
|
||||
|
||||
// expose public methods
|
||||
Object.assign(proxy, { start, stop, increment })
|
||||
|
||||
return () => h('div', {
|
||||
class: classes.value,
|
||||
style: style.value,
|
||||
...attributes.value
|
||||
})
|
||||
}
|
||||
})
|
||||
104
Frontend-Learner/node_modules/quasar/src/components/ajax-bar/QAjaxBar.json
generated
vendored
Normal file
104
Frontend-Learner/node_modules/quasar/src/components/ajax-bar/QAjaxBar.json
generated
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/ajax-bar"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"position": {
|
||||
"type": "String",
|
||||
"desc": "Position within window of where QAjaxBar should be displayed",
|
||||
"default": "'top'",
|
||||
"values": [ "'top'", "'right'", "'bottom'", "'left'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"size": {
|
||||
"extends": "size",
|
||||
"default": "'2px'"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"reverse": {
|
||||
"type": "Boolean",
|
||||
"desc": "Reverse direction of progress",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"skip-hijack": {
|
||||
"type": "Boolean",
|
||||
"desc": "Skip Ajax hijacking (not a reactive prop)",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"hijack-filter": {
|
||||
"type": "Function",
|
||||
"desc": "Filter which URL should trigger start() + stop()",
|
||||
"params": {
|
||||
"url": {
|
||||
"type": "String",
|
||||
"desc": "The URL being triggered",
|
||||
"examples": [ "'https://some.url/path'" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Boolean",
|
||||
"desc": "Should the URL received as param trigger start() + stop()?"
|
||||
},
|
||||
"category": "behavior",
|
||||
"addedIn": "v2.4.5"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"start": {
|
||||
"desc": "Emitted when bar is triggered to appear"
|
||||
},
|
||||
|
||||
"stop": {
|
||||
"desc": "Emitted when bar has finished its job"
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"start": {
|
||||
"desc": "Notify bar you are waiting for a new process to finish",
|
||||
"params": {
|
||||
"speed": {
|
||||
"type": "Number",
|
||||
"default": "300",
|
||||
"desc": "Delay (in milliseconds) between progress auto-increments; If delay is 0 then it disables auto-incrementing"
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Number",
|
||||
"desc": "Number of active simultaneous sessions"
|
||||
}
|
||||
},
|
||||
|
||||
"increment": {
|
||||
"desc": "Manually trigger a bar progress increment",
|
||||
"params": {
|
||||
"amount": {
|
||||
"type": "Number",
|
||||
"desc": "Amount (0 < x <= 100) to increment with"
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Number",
|
||||
"desc": "Number of active simultaneous sessions"
|
||||
}
|
||||
},
|
||||
|
||||
"stop": {
|
||||
"desc": "Notify bar that one process you were waiting has finished",
|
||||
"params": null,
|
||||
"returns": {
|
||||
"type": "Number",
|
||||
"desc": "Number of active simultaneous sessions"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Frontend-Learner/node_modules/quasar/src/components/ajax-bar/QAjaxBar.sass
generated
vendored
Normal file
27
Frontend-Learner/node_modules/quasar/src/components/ajax-bar/QAjaxBar.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
.q-loading-bar
|
||||
position: fixed
|
||||
z-index: $z-max
|
||||
transition: transform .5s cubic-bezier(0,0,.2,1), opacity .5s
|
||||
background: $red
|
||||
|
||||
&--top
|
||||
left: 0 #{"/* rtl:ignore */"}
|
||||
right: 0 #{"/* rtl:ignore */"}
|
||||
top: 0
|
||||
width: 100%
|
||||
&--bottom
|
||||
left: 0 #{"/* rtl:ignore */"}
|
||||
right: 0 #{"/* rtl:ignore */"}
|
||||
bottom: 0
|
||||
width: 100%
|
||||
|
||||
&--right
|
||||
top: 0
|
||||
bottom: 0
|
||||
right: 0
|
||||
height: 100%
|
||||
&--left
|
||||
top: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
height: 100%
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/ajax-bar/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/ajax-bar/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QAjaxBar from './QAjaxBar.js'
|
||||
|
||||
export {
|
||||
QAjaxBar
|
||||
}
|
||||
62
Frontend-Learner/node_modules/quasar/src/components/avatar/QAvatar.js
generated
vendored
Normal file
62
Frontend-Learner/node_modules/quasar/src/components/avatar/QAvatar.js
generated
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import QIcon from '../icon/QIcon.js'
|
||||
|
||||
import useSize, { useSizeProps } from '../../composables/private.use-size/use-size.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hMergeSlotSafely } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QAvatar',
|
||||
|
||||
props: {
|
||||
...useSizeProps,
|
||||
|
||||
fontSize: String,
|
||||
|
||||
color: String,
|
||||
textColor: String,
|
||||
|
||||
icon: String,
|
||||
square: Boolean,
|
||||
rounded: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const sizeStyle = useSize(props)
|
||||
|
||||
const classes = computed(() =>
|
||||
'q-avatar'
|
||||
+ (props.color ? ` bg-${ props.color }` : '')
|
||||
+ (props.textColor ? ` text-${ props.textColor } q-chip--colored` : '')
|
||||
+ (
|
||||
props.square === true
|
||||
? ' q-avatar--square'
|
||||
: (props.rounded === true ? ' rounded-borders' : '')
|
||||
)
|
||||
)
|
||||
|
||||
const contentStyle = computed(() => (
|
||||
props.fontSize
|
||||
? { fontSize: props.fontSize }
|
||||
: null
|
||||
))
|
||||
|
||||
return () => {
|
||||
const icon = props.icon !== void 0
|
||||
? [ h(QIcon, { name: props.icon }) ]
|
||||
: void 0
|
||||
|
||||
return h('div', {
|
||||
class: classes.value,
|
||||
style: sizeStyle.value
|
||||
}, [
|
||||
h('div', {
|
||||
class: 'q-avatar__content row flex-center overflow-hidden',
|
||||
style: contentStyle.value
|
||||
}, hMergeSlotSafely(slots.default, icon))
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
||||
42
Frontend-Learner/node_modules/quasar/src/components/avatar/QAvatar.json
generated
vendored
Normal file
42
Frontend-Learner/node_modules/quasar/src/components/avatar/QAvatar.json
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"mixins": [ "composables/private.use-size/use-size" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/avatar"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"font-size": {
|
||||
"type": "String",
|
||||
"desc": "The size in CSS units, including unit name, of the content (icon, text)",
|
||||
"examples": [ "'18px'", "'2rem'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"text-color": {
|
||||
"extends": "text-color"
|
||||
},
|
||||
|
||||
"icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"square": {
|
||||
"extends": "square"
|
||||
},
|
||||
|
||||
"rounded": {
|
||||
"extends": "rounded"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Optional; Suggestions: one character string, <img> tag"
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Frontend-Learner/node_modules/quasar/src/components/avatar/QAvatar.sass
generated
vendored
Normal file
22
Frontend-Learner/node_modules/quasar/src/components/avatar/QAvatar.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
.q-avatar
|
||||
position: relative
|
||||
vertical-align: middle
|
||||
display: inline-block
|
||||
|
||||
border-radius: 50%
|
||||
|
||||
font-size: $avatar-font-size
|
||||
height: 1em
|
||||
width: 1em
|
||||
|
||||
&__content
|
||||
font-size: $avatar-content-font-size
|
||||
line-height: $avatar-content-line-height
|
||||
|
||||
&__content, img:not(.q-icon):not(.q-img__image)
|
||||
border-radius: inherit
|
||||
height: inherit
|
||||
width: inherit
|
||||
|
||||
&--square
|
||||
border-radius: 0
|
||||
204
Frontend-Learner/node_modules/quasar/src/components/avatar/QAvatar.test.js
generated
vendored
Normal file
204
Frontend-Learner/node_modules/quasar/src/components/avatar/QAvatar.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
import QAvatar from './QAvatar.js'
|
||||
import { useSizeDefaults } from 'quasar/src/composables/private.use-size/use-size.js'
|
||||
|
||||
describe('[QAvatar API]', () => {
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)size]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const wrapper = mount(QAvatar)
|
||||
const target = wrapper.get('.q-avatar')
|
||||
|
||||
expect(
|
||||
target.$style('font-size')
|
||||
).toBe('')
|
||||
|
||||
await wrapper.setProps({ size: '100px' })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.$style('font-size')
|
||||
).toContain('100px')
|
||||
|
||||
await wrapper.setProps({ size: 'sm' })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.$style('font-size')
|
||||
).toBe(`${ useSizeDefaults.sm }px`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)font-size]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const size = '200px'
|
||||
const fontSize = '100px'
|
||||
|
||||
const wrapper = mount(QAvatar)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-avatar')
|
||||
.$style('font-size')
|
||||
).not.toBe(size)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-avatar__content')
|
||||
.$style('font-size')
|
||||
).not.toBe(fontSize)
|
||||
|
||||
await wrapper.setProps({
|
||||
size,
|
||||
fontSize
|
||||
})
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-avatar')
|
||||
.$style('font-size')
|
||||
).toBe(size)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-avatar__content')
|
||||
.$style('font-size')
|
||||
).toBe(fontSize)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)color]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QAvatar)
|
||||
const target = wrapper.get('.q-avatar')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`bg-${ propVal }`)
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`text-${ propVal }`)
|
||||
|
||||
await wrapper.setProps({ color: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain(`bg-${ propVal }`)
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`text-${ propVal }`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)text-color]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QAvatar)
|
||||
const target = wrapper.get('.q-avatar')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`bg-${ propVal }`)
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`text-${ propVal }`)
|
||||
|
||||
await wrapper.setProps({ textColor: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain(`text-${ propVal }`)
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`bg-${ propVal }`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)icon]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'map'
|
||||
const wrapper = mount(QAvatar)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-avatar')
|
||||
.find('.q-icon')
|
||||
.exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ icon: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-avatar')
|
||||
.get('.q-icon')
|
||||
.text()
|
||||
).toContain(`${ propVal }`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)square]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QAvatar)
|
||||
const target = wrapper.get('.q-avatar')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-avatar--square')
|
||||
|
||||
await wrapper.setProps({ square: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-avatar--square')
|
||||
|
||||
expect(
|
||||
target.$computedStyle('border-radius')
|
||||
).not.toBe('0px')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)rounded]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QAvatar)
|
||||
const target = wrapper.get('.q-avatar')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('rounded-borders')
|
||||
|
||||
await wrapper.setProps({ rounded: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.$computedStyle('border-radius')
|
||||
).toBe('4px')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('rounded-borders')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Slots]', () => {
|
||||
describe('[(slot)default]', () => {
|
||||
test('renders the content', () => {
|
||||
const slotContent = 'some-slot-content'
|
||||
const wrapper = mount(QAvatar, {
|
||||
slots: {
|
||||
default: () => slotContent
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).toContain(slotContent)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/avatar/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/avatar/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QAvatar from './QAvatar.js'
|
||||
|
||||
export {
|
||||
QAvatar
|
||||
}
|
||||
60
Frontend-Learner/node_modules/quasar/src/components/badge/QBadge.js
generated
vendored
Normal file
60
Frontend-Learner/node_modules/quasar/src/components/badge/QBadge.js
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hMergeSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
const alignValues = [ 'top', 'middle', 'bottom' ]
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBadge',
|
||||
|
||||
props: {
|
||||
color: String,
|
||||
textColor: String,
|
||||
|
||||
floating: Boolean,
|
||||
transparent: Boolean,
|
||||
multiLine: Boolean,
|
||||
outline: Boolean,
|
||||
rounded: Boolean,
|
||||
|
||||
label: [ Number, String ],
|
||||
|
||||
align: {
|
||||
type: String,
|
||||
validator: v => alignValues.includes(v)
|
||||
}
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const style = computed(() => {
|
||||
return props.align !== void 0
|
||||
? { verticalAlign: props.align }
|
||||
: null
|
||||
})
|
||||
|
||||
const classes = computed(() => {
|
||||
const text = props.outline === true
|
||||
? props.color || props.textColor
|
||||
: props.textColor
|
||||
|
||||
return 'q-badge flex inline items-center no-wrap'
|
||||
+ ` q-badge--${ props.multiLine === true ? 'multi' : 'single' }-line`
|
||||
+ (props.outline === true
|
||||
? ' q-badge--outline'
|
||||
: (props.color !== void 0 ? ` bg-${ props.color }` : '')
|
||||
)
|
||||
+ (text !== void 0 ? ` text-${ text }` : '')
|
||||
+ (props.floating === true ? ' q-badge--floating' : '')
|
||||
+ (props.rounded === true ? ' q-badge--rounded' : '')
|
||||
+ (props.transparent === true ? ' q-badge--transparent' : '')
|
||||
})
|
||||
|
||||
return () => h('div', {
|
||||
class: classes.value,
|
||||
style: style.value,
|
||||
role: 'status',
|
||||
'aria-label': props.label
|
||||
}, hMergeSlot(slots.default, props.label !== void 0 ? [ props.label ] : []))
|
||||
}
|
||||
})
|
||||
65
Frontend-Learner/node_modules/quasar/src/components/badge/QBadge.json
generated
vendored
Normal file
65
Frontend-Learner/node_modules/quasar/src/components/badge/QBadge.json
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/badge"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"text-color": {
|
||||
"extends": "text-color"
|
||||
},
|
||||
|
||||
"floating": {
|
||||
"type": "Boolean",
|
||||
"desc": "Tell QBadge if it should float to the top right side of the relative positioned parent element or not",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"transparent": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a 0.8 opacity; Useful especially for floating QBadge",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"multi-line": {
|
||||
"type": "Boolean",
|
||||
"desc": "Content can wrap to multiple lines",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"label": {
|
||||
"type": [ "String", "Number" ],
|
||||
"desc": "Badge's content as string; overrides default slot if specified",
|
||||
"examples": [ "'John Doe'", "22" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"align": {
|
||||
"type": "String",
|
||||
"desc": "Sets vertical-align CSS prop",
|
||||
"values": [ "'top'", "'middle'", "'bottom'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"outline": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'outline' design (colored text and borders only)",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"rounded": {
|
||||
"type": "Boolean",
|
||||
"desc": "Makes a rounded shaped badge",
|
||||
"category": "style"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "This is where QBadge content goes, if not using 'label' property"
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Frontend-Learner/node_modules/quasar/src/components/badge/QBadge.sass
generated
vendored
Normal file
32
Frontend-Learner/node_modules/quasar/src/components/badge/QBadge.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
.q-badge
|
||||
background-color: var(--q-primary)
|
||||
color: #fff
|
||||
padding: 2px 6px
|
||||
border-radius: $generic-border-radius
|
||||
font-size: $badge-font-size
|
||||
line-height: $badge-line-height
|
||||
min-height: $badge-min-height
|
||||
font-weight: normal
|
||||
vertical-align: baseline
|
||||
|
||||
&--single-line
|
||||
white-space: nowrap
|
||||
&--multi-line
|
||||
word-break: break-all
|
||||
word-wrap: break-word
|
||||
|
||||
&--floating
|
||||
position: absolute
|
||||
top: -4px
|
||||
right: -3px
|
||||
cursor: inherit
|
||||
|
||||
&--transparent
|
||||
opacity: .8
|
||||
|
||||
&--outline
|
||||
background-color: transparent
|
||||
border: 1px solid currentColor
|
||||
|
||||
&--rounded
|
||||
border-radius: 1em
|
||||
231
Frontend-Learner/node_modules/quasar/src/components/badge/QBadge.test.js
generated
vendored
Normal file
231
Frontend-Learner/node_modules/quasar/src/components/badge/QBadge.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
import QBadge from './QBadge.js'
|
||||
|
||||
describe('[QBadge API]', () => {
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)color]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`bg-${ propVal }`)
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`text-${ propVal }`)
|
||||
|
||||
await wrapper.setProps({ color: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain(`bg-${ propVal }`)
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`text-${ propVal }`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)text-color]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`bg-${ propVal }`)
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`text-${ propVal }`)
|
||||
|
||||
await wrapper.setProps({ textColor: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain(`text-${ propVal }`)
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain(`bg-${ propVal }`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)floating]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-badge--floating')
|
||||
|
||||
await wrapper.setProps({ floating: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.classes()
|
||||
).toContain('q-badge--floating')
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-badge')
|
||||
.$computedStyle('position')
|
||||
).toBe('absolute')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)transparent]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-badge--transparent')
|
||||
|
||||
await wrapper.setProps({ transparent: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-badge--transparent')
|
||||
|
||||
expect(
|
||||
target.$computedStyle('opacity')
|
||||
).not.toBe('1')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)multi-line]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-badge--multi-line')
|
||||
|
||||
await wrapper.setProps({ multiLine: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-badge--multi-line')
|
||||
|
||||
expect(
|
||||
target.$computedStyle('word-break')
|
||||
).toBe('break-all')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)label]', () => {
|
||||
test.each([
|
||||
[ 'String', 'John Doe' ],
|
||||
[ 'Number', 22 ]
|
||||
])('type %s has effect', async (_, propVal) => {
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.text()
|
||||
).not.toContain(propVal)
|
||||
|
||||
await wrapper.setProps({ label: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.text()
|
||||
).toContain(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)align]', () => {
|
||||
test.each([
|
||||
[ 'top' ],
|
||||
[ 'middle' ],
|
||||
[ 'bottom' ]
|
||||
])('value "%s" has effect', async propVal => {
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.$style('vertical-align')
|
||||
).not.toBe(propVal)
|
||||
|
||||
await wrapper.setProps({ align: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.$style('vertical-align')
|
||||
).toBe(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)outline]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-badge--outline')
|
||||
|
||||
await wrapper.setProps({ outline: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-badge--outline')
|
||||
|
||||
expect(
|
||||
target.$computedStyle('border')
|
||||
).toContain('1px solid')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)rounded]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBadge)
|
||||
const target = wrapper.get('.q-badge')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-badge--rounded')
|
||||
|
||||
await wrapper.setProps({ rounded: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-badge--rounded')
|
||||
|
||||
expect(
|
||||
target.$computedStyle('border-radius')
|
||||
).toBe('1em')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Slots]', () => {
|
||||
describe('[(slot)default]', () => {
|
||||
test('renders the content', () => {
|
||||
const slotContent = 'some-slot-content'
|
||||
const wrapper = mount(QBadge, {
|
||||
slots: {
|
||||
default: () => slotContent
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).toContain(slotContent)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/badge/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/badge/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QBadge from './QBadge.js'
|
||||
|
||||
export {
|
||||
QBadge
|
||||
}
|
||||
58
Frontend-Learner/node_modules/quasar/src/components/banner/QBanner.js
generated
vendored
Normal file
58
Frontend-Learner/node_modules/quasar/src/components/banner/QBanner.js
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { h, computed, getCurrentInstance } from 'vue'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js'
|
||||
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBanner',
|
||||
|
||||
props: {
|
||||
...useDarkProps,
|
||||
|
||||
inlineActions: Boolean,
|
||||
dense: Boolean,
|
||||
rounded: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const { proxy: { $q } } = getCurrentInstance()
|
||||
const isDark = useDark(props, $q)
|
||||
|
||||
const classes = computed(() =>
|
||||
'q-banner row items-center'
|
||||
+ (props.dense === true ? ' q-banner--dense' : '')
|
||||
+ (isDark.value === true ? ' q-banner--dark q-dark' : '')
|
||||
+ (props.rounded === true ? ' rounded-borders' : '')
|
||||
)
|
||||
|
||||
const actionClass = computed(() =>
|
||||
'q-banner__actions row items-center justify-end'
|
||||
+ ` col-${ props.inlineActions === true ? 'auto' : 'all' }`
|
||||
)
|
||||
|
||||
return () => {
|
||||
const child = [
|
||||
h('div', {
|
||||
class: 'q-banner__avatar col-auto row items-center self-start'
|
||||
}, hSlot(slots.avatar)),
|
||||
|
||||
h('div', {
|
||||
class: 'q-banner__content col text-body2'
|
||||
}, hSlot(slots.default))
|
||||
]
|
||||
|
||||
const actions = hSlot(slots.action)
|
||||
actions !== void 0 && child.push(
|
||||
h('div', { class: actionClass.value }, actions)
|
||||
)
|
||||
|
||||
return h('div', {
|
||||
class: classes.value
|
||||
+ (props.inlineActions === false && actions !== void 0 ? ' q-banner--top-padding' : ''),
|
||||
role: 'alert'
|
||||
}, child)
|
||||
}
|
||||
}
|
||||
})
|
||||
39
Frontend-Learner/node_modules/quasar/src/components/banner/QBanner.json
generated
vendored
Normal file
39
Frontend-Learner/node_modules/quasar/src/components/banner/QBanner.json
generated
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/banner"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"inline-actions": {
|
||||
"type": "Boolean",
|
||||
"desc": "Display actions on same row as content",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"dense": {
|
||||
"extends": "dense"
|
||||
},
|
||||
|
||||
"rounded": {
|
||||
"extends": "rounded"
|
||||
},
|
||||
|
||||
"dark": {
|
||||
"extends": "dark"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "This is where Banner content goes"
|
||||
},
|
||||
|
||||
"avatar": {
|
||||
"desc": "Slot for displaying an avatar (suggestions: QIcon, QAvatar)"
|
||||
},
|
||||
|
||||
"action": {
|
||||
"desc": "Slot for Banner action (suggestions: QBtn)"
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Frontend-Learner/node_modules/quasar/src/components/banner/QBanner.sass
generated
vendored
Normal file
38
Frontend-Learner/node_modules/quasar/src/components/banner/QBanner.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
.q-banner
|
||||
min-height: 54px
|
||||
padding: 8px 16px
|
||||
background: #fff
|
||||
|
||||
&--top-padding
|
||||
padding-top: 14px
|
||||
|
||||
&__avatar
|
||||
min-width: 1px !important
|
||||
> .q-avatar
|
||||
font-size: $banner-avatar-font-size
|
||||
> .q-icon
|
||||
font-size: $banner-avatar-icon-font-size
|
||||
|
||||
&__avatar:not(:empty) + &__content
|
||||
padding-left: 16px
|
||||
|
||||
&__actions
|
||||
&.col-auto
|
||||
padding-left: 16px
|
||||
&.col-all
|
||||
.q-btn-item
|
||||
margin: 4px 0 0 4px
|
||||
|
||||
&--dense
|
||||
min-height: 32px
|
||||
padding: 8px
|
||||
&.q-banner--top-padding
|
||||
padding-top: 12px
|
||||
.q-banner__avatar
|
||||
> .q-avatar, > .q-icon
|
||||
font-size: $banner-avatar-dense-font-size
|
||||
.q-banner__avatar:not(:empty) + .q-banner__content
|
||||
padding-left: 8px
|
||||
.q-banner__actions
|
||||
&.col-auto
|
||||
padding-left: 8px
|
||||
145
Frontend-Learner/node_modules/quasar/src/components/banner/QBanner.test.js
generated
vendored
Normal file
145
Frontend-Learner/node_modules/quasar/src/components/banner/QBanner.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
import QBanner from './QBanner.js'
|
||||
|
||||
describe('[QBanner API]', () => {
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)inline-actions]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBanner, {
|
||||
slots: {
|
||||
action: () => 'Banner action'
|
||||
}
|
||||
})
|
||||
|
||||
const target = wrapper
|
||||
.get('.q-banner')
|
||||
.get('.q-banner__actions')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('col-auto')
|
||||
|
||||
await wrapper.setProps({ inlineActions: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('col-auto')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)dense]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBanner)
|
||||
const target = wrapper.get('.q-banner')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-banner--dense')
|
||||
|
||||
await wrapper.setProps({ dense: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-banner--dense')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)rounded]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBanner)
|
||||
const target = wrapper.get('.q-banner')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('rounded-borders')
|
||||
|
||||
await wrapper.setProps({ rounded: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('rounded-borders')
|
||||
|
||||
expect(
|
||||
target.$computedStyle('border-radius')
|
||||
).toBe('4px')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)dark]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBanner)
|
||||
const target = wrapper.get('.q-banner')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-banner--dark')
|
||||
|
||||
await wrapper.setProps({ dark: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-banner--dark')
|
||||
})
|
||||
|
||||
test('type null has effect', async () => {
|
||||
const wrapper = mount(QBanner, {
|
||||
props: {
|
||||
dark: null
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-banner')
|
||||
.classes()
|
||||
).not.toContain('q-banner--dark')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Slots]', () => {
|
||||
describe('[(slot)default]', () => {
|
||||
test('renders the content', () => {
|
||||
const slotContent = 'some-slot-content'
|
||||
const wrapper = mount(QBanner, {
|
||||
slots: {
|
||||
default: () => slotContent
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).toContain(slotContent)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(slot)avatar]', () => {
|
||||
test('renders the content', () => {
|
||||
const slotContent = 'some-slot-content'
|
||||
const wrapper = mount(QBanner, {
|
||||
slots: {
|
||||
avatar: () => slotContent
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).toContain(slotContent)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(slot)action]', () => {
|
||||
test('renders the content', () => {
|
||||
const slotContent = 'some-slot-content'
|
||||
const wrapper = mount(QBanner, {
|
||||
slots: {
|
||||
action: () => slotContent
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).toContain(slotContent)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/banner/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/banner/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QBanner from './QBanner.js'
|
||||
|
||||
export {
|
||||
QBanner
|
||||
}
|
||||
31
Frontend-Learner/node_modules/quasar/src/components/bar/QBar.js
generated
vendored
Normal file
31
Frontend-Learner/node_modules/quasar/src/components/bar/QBar.js
generated
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { h, computed, getCurrentInstance } from 'vue'
|
||||
|
||||
import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBar',
|
||||
|
||||
props: {
|
||||
...useDarkProps,
|
||||
dense: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const { proxy: { $q } } = getCurrentInstance()
|
||||
const isDark = useDark(props, $q)
|
||||
|
||||
const classes = computed(() =>
|
||||
'q-bar row no-wrap items-center'
|
||||
+ ` q-bar--${ props.dense === true ? 'dense' : 'standard' } `
|
||||
+ ` q-bar--${ isDark.value === true ? 'dark' : 'light' }`
|
||||
)
|
||||
|
||||
return () => h('div', {
|
||||
class: classes.value,
|
||||
role: 'toolbar'
|
||||
}, hSlot(slots.default))
|
||||
}
|
||||
})
|
||||
22
Frontend-Learner/node_modules/quasar/src/components/bar/QBar.json
generated
vendored
Normal file
22
Frontend-Learner/node_modules/quasar/src/components/bar/QBar.json
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/bar"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"dense": {
|
||||
"extends": "dense"
|
||||
},
|
||||
|
||||
"dark": {
|
||||
"extends": "dark",
|
||||
"desc": "The component background color lights up the parent's background (as opposed to default behavior which is to darken it); Works unless you specify a CSS background color for it"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"extends": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Frontend-Learner/node_modules/quasar/src/components/bar/QBar.sass
generated
vendored
Normal file
31
Frontend-Learner/node_modules/quasar/src/components/bar/QBar.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
.q-bar
|
||||
background: rgba(0,0,0,.2)
|
||||
|
||||
> .q-icon
|
||||
margin-left: 2px
|
||||
> div, > div + .q-icon
|
||||
margin-left: 8px
|
||||
> .q-btn
|
||||
margin-left: 2px
|
||||
|
||||
> .q-icon:first-child, > .q-btn:first-child, > div:first-child
|
||||
margin-left: 0
|
||||
|
||||
&--standard
|
||||
padding: 0 12px
|
||||
height: $bar-height
|
||||
font-size: 18px
|
||||
> div
|
||||
font-size: $bar-inner-font-size
|
||||
.q-btn
|
||||
font-size: $bar-button-font-size
|
||||
|
||||
&--dense
|
||||
padding: 0 8px
|
||||
height: $bar-dense-height
|
||||
font-size: $bar-dense-font-size
|
||||
.q-btn
|
||||
font-size: $bar-dense-button-font-size
|
||||
|
||||
&--dark
|
||||
background: rgba(255,255,255,.15)
|
||||
72
Frontend-Learner/node_modules/quasar/src/components/bar/QBar.test.js
generated
vendored
Normal file
72
Frontend-Learner/node_modules/quasar/src/components/bar/QBar.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
import QBar from './QBar.js'
|
||||
|
||||
describe('[QBar API]', () => {
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)dense]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBar)
|
||||
const target = wrapper.get('.q-bar')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-bar--dense')
|
||||
|
||||
await wrapper.setProps({ dense: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-bar--dense')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)dark]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QBar)
|
||||
const target = wrapper.get('.q-bar')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-bar--dark')
|
||||
|
||||
await wrapper.setProps({ dark: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-bar--dark')
|
||||
})
|
||||
|
||||
test('type null has effect', async () => {
|
||||
const wrapper = mount(QBar, {
|
||||
props: {
|
||||
dark: null
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-bar')
|
||||
.classes()
|
||||
).not.toContain('q-bar--dark')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Slots]', () => {
|
||||
describe('[(slot)default]', () => {
|
||||
test('renders the content', () => {
|
||||
const slotContent = 'some-slot-content'
|
||||
const wrapper = mount(QBar, {
|
||||
slots: {
|
||||
default: () => slotContent
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).toContain(slotContent)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/bar/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/bar/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QBar from './QBar.js'
|
||||
|
||||
export {
|
||||
QBar
|
||||
}
|
||||
98
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbs.js
generated
vendored
Normal file
98
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbs.js
generated
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import useAlign, { useAlignProps } from '../../composables/private.use-align/use-align.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
import { getNormalizedVNodes } from '../../utils/private.vm/vm.js'
|
||||
|
||||
const disabledValues = [ '', true ]
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBreadcrumbs',
|
||||
|
||||
props: {
|
||||
...useAlignProps,
|
||||
|
||||
separator: {
|
||||
type: String,
|
||||
default: '/'
|
||||
},
|
||||
separatorColor: String,
|
||||
|
||||
activeColor: {
|
||||
type: String,
|
||||
default: 'primary'
|
||||
},
|
||||
|
||||
gutter: {
|
||||
type: String,
|
||||
validator: v => [ 'none', 'xs', 'sm', 'md', 'lg', 'xl' ].includes(v),
|
||||
default: 'sm'
|
||||
}
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const alignClass = useAlign(props)
|
||||
|
||||
const classes = computed(() =>
|
||||
`flex items-center ${ alignClass.value }${ props.gutter === 'none' ? '' : ` q-gutter-${ props.gutter }` }`
|
||||
)
|
||||
|
||||
const sepClass = computed(() => (props.separatorColor ? ` text-${ props.separatorColor }` : ''))
|
||||
const activeClass = computed(() => ` text-${ props.activeColor }`)
|
||||
|
||||
return () => {
|
||||
if (slots.default === void 0) return
|
||||
|
||||
const vnodes = getNormalizedVNodes(
|
||||
hSlot(slots.default)
|
||||
)
|
||||
|
||||
if (vnodes.length === 0) return
|
||||
|
||||
let els = 1
|
||||
|
||||
const
|
||||
child = [],
|
||||
len = vnodes.filter(c => c.type?.name === 'QBreadcrumbsEl').length,
|
||||
separator = slots.separator !== void 0
|
||||
? slots.separator
|
||||
: () => props.separator
|
||||
|
||||
vnodes.forEach(comp => {
|
||||
if (comp.type?.name === 'QBreadcrumbsEl') {
|
||||
const middle = els < len
|
||||
const disabled = comp.props !== null && disabledValues.includes(comp.props.disable)
|
||||
const cls = (middle === true ? '' : ' q-breadcrumbs--last')
|
||||
+ (disabled !== true && middle === true ? activeClass.value : '')
|
||||
|
||||
els++
|
||||
|
||||
child.push(
|
||||
h('div', {
|
||||
class: `flex items-center${ cls }`
|
||||
}, [ comp ])
|
||||
)
|
||||
|
||||
if (middle === true) {
|
||||
child.push(
|
||||
h('div', {
|
||||
class: 'q-breadcrumbs__separator' + sepClass.value
|
||||
}, separator())
|
||||
)
|
||||
}
|
||||
}
|
||||
else {
|
||||
child.push(comp)
|
||||
}
|
||||
})
|
||||
|
||||
return h('div', {
|
||||
class: 'q-breadcrumbs'
|
||||
}, [
|
||||
h('div', { class: classes.value }, child)
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
||||
55
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbs.json
generated
vendored
Normal file
55
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbs.json
generated
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/breadcrumbs"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"separator": {
|
||||
"type": "String",
|
||||
"desc": "The string used to separate the breadcrumbs",
|
||||
"default": "'/'",
|
||||
"examples": [ "'-'", "'|'", "'>'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"active-color": {
|
||||
"extends": "color",
|
||||
"desc": "The color of the active breadcrumb, which can be any color from the Quasar Color Palette",
|
||||
"default": "'primary'",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"gutter": {
|
||||
"type": "String",
|
||||
"desc": "The gutter value allows you control over the space between the breadcrumb elements.",
|
||||
"default": "'sm'",
|
||||
"values": [ "'none'", "'xs'", "'sm'", "'md'", "'lg'", "'xl'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"separator-color": {
|
||||
"extends": "color",
|
||||
"desc": "The color used to color the separator, which can be any color from the Quasar Color Palette",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"align": {
|
||||
"type": "String",
|
||||
"desc": "Specify how to align the breadcrumbs horizontally",
|
||||
"values": [ "'left'", "'center'", "'right'", "'between'", "'around'", "'evenly'" ],
|
||||
"default": "'left'",
|
||||
"__runtimeDefault": true,
|
||||
"category": "content"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"extends": "default"
|
||||
},
|
||||
|
||||
"separator": {
|
||||
"desc": "HTML or component you can slot in to separate the breadcrumbs"
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbs.sass
generated
vendored
Normal file
13
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbs.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
.q-breadcrumbs
|
||||
|
||||
&__el
|
||||
color: inherit
|
||||
|
||||
&__el-icon
|
||||
font-size: $breadcrumbs-icon-font-size
|
||||
|
||||
&--with-label
|
||||
margin-right: 8px
|
||||
|
||||
[dir=rtl] .q-breadcrumbs__separator .q-icon
|
||||
transform: scaleX(-1) #{"/* rtl:ignore */"}
|
||||
178
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbs.test.js
generated
vendored
Normal file
178
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbs.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
// import QBreadcrumbs from './QBreadcrumbs.js'
|
||||
|
||||
import { alignMap } from 'quasar/src/composables/private.use-align/use-align.js'
|
||||
|
||||
import BasicBreadcrumbs from './test/BasicBreadcrumbs.vue'
|
||||
import BreadcrumbWithSeparatorSlot from './test/BreadcrumbWithSeparatorSlot.vue'
|
||||
|
||||
describe('[QBreadcrumbs API]', () => {
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)separator]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = '>'
|
||||
const wrapper = mount(BasicBreadcrumbs)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs__separator')
|
||||
.text()
|
||||
).not.toContain(propVal)
|
||||
|
||||
await wrapper.setProps({ separator: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs__separator')
|
||||
.text()
|
||||
).toContain(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)active-color]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(BasicBreadcrumbs)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div > .flex.items-center:not(.q-breadcrumbs--last)')
|
||||
.classes()
|
||||
).not.toContain('text-red')
|
||||
|
||||
await wrapper.setProps({ activeColor: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div > .flex.items-center:not(.q-breadcrumbs--last)')
|
||||
.classes()
|
||||
).toContain('text-red')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)gutter]', () => {
|
||||
test('value "none" has effect', async () => {
|
||||
const propVal = 'none'
|
||||
const wrapper = mount(BasicBreadcrumbs)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div')
|
||||
.classes()
|
||||
).toContain('q-gutter-sm')
|
||||
|
||||
await wrapper.setProps({ gutter: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div')
|
||||
.classes()
|
||||
).toSatisfy(
|
||||
list => list.every(cls => cls.startsWith('q-gutter') === false)
|
||||
)
|
||||
})
|
||||
|
||||
test.each([
|
||||
[ 'xs' ],
|
||||
[ 'sm' ],
|
||||
[ 'md' ],
|
||||
[ 'lg' ],
|
||||
[ 'xl' ]
|
||||
])('value %s has effect', async propVal => {
|
||||
const wrapper = mount(BasicBreadcrumbs)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div')
|
||||
.classes()
|
||||
).toContain('q-gutter-sm')
|
||||
|
||||
await wrapper.setProps({ gutter: propVal })
|
||||
await flushPromises()
|
||||
|
||||
if (propVal !== 'sm') {
|
||||
// the default value
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div')
|
||||
.classes()
|
||||
).not.toContain('q-gutter-sm')
|
||||
}
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div')
|
||||
.classes()
|
||||
).toContain(`q-gutter-${ propVal }`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)separator-color]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(BasicBreadcrumbs)
|
||||
|
||||
wrapper.findAll('.q-breadcrumbs__separator')
|
||||
.forEach(el => expect(el.classes()).not.toContain('text-red'))
|
||||
|
||||
// TODO: write expectations without the prop
|
||||
// (usually negate the effect of the prop)
|
||||
|
||||
await wrapper.setProps({ separatorColor: propVal })
|
||||
await flushPromises()
|
||||
|
||||
wrapper.findAll('.q-breadcrumbs__separator')
|
||||
.forEach(el => expect(el.classes()).toContain('text-red'))
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)align]', () => {
|
||||
test.each([
|
||||
[ 'left' ],
|
||||
[ 'center' ],
|
||||
[ 'right' ],
|
||||
[ 'between' ],
|
||||
[ 'around' ],
|
||||
[ 'evenly' ]
|
||||
])('value "%s" has effect', async propVal => {
|
||||
const wrapper = mount(BasicBreadcrumbs)
|
||||
|
||||
if (propVal !== 'left') {
|
||||
// the default value
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div')
|
||||
.classes()
|
||||
).not.toContain(`justify-${ alignMap[ propVal ] }`)
|
||||
}
|
||||
|
||||
await wrapper.setProps({ align: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div')
|
||||
.classes()
|
||||
).toContain(`justify-${ alignMap[ propVal ] }`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Slots]', () => {
|
||||
describe('[(slot)default]', () => {
|
||||
test('renders the content', () => {
|
||||
const wrapper = mount(BasicBreadcrumbs)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs > div')
|
||||
.text()
|
||||
).toContain('Home')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(slot)separator]', () => {
|
||||
test('renders the content', () => {
|
||||
const wrapper = mount(BreadcrumbWithSeparatorSlot)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-breadcrumbs__separator')
|
||||
.text()
|
||||
).toContain('arrow_forward')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
63
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbsEl.js
generated
vendored
Normal file
63
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbsEl.js
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import QIcon from '../icon/QIcon.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hMergeSlot } from '../../utils/private.render/render.js'
|
||||
import useRouterLink, { useRouterLinkProps } from '../../composables/private.use-router-link/use-router-link.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBreadcrumbsEl',
|
||||
|
||||
props: {
|
||||
...useRouterLinkProps,
|
||||
|
||||
label: String,
|
||||
icon: String,
|
||||
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'span'
|
||||
}
|
||||
},
|
||||
|
||||
emits: [ 'click' ],
|
||||
|
||||
setup (props, { slots }) {
|
||||
const { linkTag, linkAttrs, linkClass, navigateOnClick } = useRouterLink()
|
||||
|
||||
const data = computed(() => {
|
||||
return {
|
||||
class: 'q-breadcrumbs__el q-link '
|
||||
+ 'flex inline items-center relative-position '
|
||||
+ (props.disable !== true ? 'q-link--focusable' + linkClass.value : 'q-breadcrumbs__el--disable'),
|
||||
...linkAttrs.value,
|
||||
onClick: navigateOnClick
|
||||
}
|
||||
})
|
||||
|
||||
const iconClass = computed(() =>
|
||||
'q-breadcrumbs__el-icon'
|
||||
+ (props.label !== void 0 ? ' q-breadcrumbs__el-icon--with-label' : '')
|
||||
)
|
||||
|
||||
return () => {
|
||||
const child = []
|
||||
|
||||
props.icon !== void 0 && child.push(
|
||||
h(QIcon, {
|
||||
class: iconClass.value,
|
||||
name: props.icon
|
||||
})
|
||||
)
|
||||
|
||||
props.label !== void 0 && child.push(props.label)
|
||||
|
||||
return h(
|
||||
linkTag.value,
|
||||
{ ...data.value },
|
||||
hMergeSlot(slots.default, child)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
84
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbsEl.json
generated
vendored
Normal file
84
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbsEl.json
generated
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/breadcrumbs"
|
||||
},
|
||||
|
||||
"mixins": [ "composables/private.use-router-link/use-router-link" ],
|
||||
|
||||
"props": {
|
||||
"label": {
|
||||
"type": "String",
|
||||
"desc": "The label text for the breadcrumb",
|
||||
"examples": [ "'Home'", "'Index'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"tag": {
|
||||
"extends": "tag",
|
||||
"default": "'span'",
|
||||
"examples": [ "'div'", "'span'" ]
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "This is where custom content goes, unless 'icon' and 'label' props are not enough"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"click": {
|
||||
"desc": "Emitted when the component is clicked",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"desc": "JS event object; If you are using route navigation ('to'/'replace' props) and you want to cancel navigation then call evt.preventDefault() synchronously in your event handler"
|
||||
},
|
||||
"go": {
|
||||
"type": "Function",
|
||||
"desc": "Available ONLY if you are using route navigation ('to'/'replace' props); When you need to control the time at which the component should trigger the route navigation then call evt.preventDefault() synchronously and then call this function at your convenience; Useful if you have async work to be done before the actual route navigation or if you want to redirect somewhere else",
|
||||
"required": false,
|
||||
"addedIn": "v2.9",
|
||||
"params": {
|
||||
"opts": {
|
||||
"type": "Object",
|
||||
"desc": "Optional options",
|
||||
"required": false,
|
||||
"definition": {
|
||||
"to": {
|
||||
"type": [ "String", "Object" ],
|
||||
"desc": "Equivalent to Vue Router <router-link> 'to' property; Specify it explicitly otherwise it will be set with same value as component's 'to' prop",
|
||||
"required": false,
|
||||
"examples": [
|
||||
"'/home/dashboard'",
|
||||
"{ name: 'my-route-name' }"
|
||||
]
|
||||
},
|
||||
|
||||
"replace": {
|
||||
"type": "Boolean",
|
||||
"desc": "Equivalent to Vue Router <router-link> 'replace' property; Specify it explicitly otherwise it will be set with same value as component's 'replace' prop",
|
||||
"required": false
|
||||
},
|
||||
|
||||
"returnRouterError": {
|
||||
"type": "Boolean",
|
||||
"desc": "Return the router error, if any; Otherwise the returned Promise will always fulfill",
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Promise<any>",
|
||||
"desc": "Returns the router's navigation promise"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
513
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbsEl.test.js
generated
vendored
Normal file
513
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/QBreadcrumbsEl.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { describe, test, expect, vi } from 'vitest'
|
||||
|
||||
import QBreadcrumbsEl from './QBreadcrumbsEl.js'
|
||||
import { getRouter } from 'testing/runtime/router.js'
|
||||
|
||||
describe('[QBreadcrumbsEl API]', () => {
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)to]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const testRoute = '/home/dashboard'
|
||||
const router = await getRouter(testRoute)
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ to: testRoute })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('a').attributes('href')
|
||||
).toBe(testRoute)
|
||||
|
||||
const routerFn = vi.spyOn(router, 'push')
|
||||
|
||||
await wrapper.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).toBe(testRoute)
|
||||
|
||||
expect(routerFn).toHaveBeenCalledTimes(1)
|
||||
expect(routerFn).toHaveBeenCalledWith(testRoute)
|
||||
})
|
||||
|
||||
test('type Object has effect', async () => {
|
||||
const testRoute = '/my-route-name'
|
||||
const propVal = { path: testRoute }
|
||||
const router = await getRouter(testRoute)
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ to: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('a').attributes('href')
|
||||
).toBe(testRoute)
|
||||
|
||||
const routerFn = vi.spyOn(router, 'push')
|
||||
|
||||
await wrapper.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).toBe(testRoute)
|
||||
|
||||
expect(routerFn).toHaveBeenCalledTimes(1)
|
||||
expect(routerFn).toHaveBeenCalledWith(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)exact]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const activeClass = 'it-is-active'
|
||||
const exactActiveClass = 'it-is-exact-active'
|
||||
const router = await getRouter({ '/route': 'subRoute' })
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
exact: true,
|
||||
activeClass,
|
||||
exactActiveClass
|
||||
},
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ to: '/route/subRoute' })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('a').attributes('href')
|
||||
).toBe('/route/subRoute')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).not.toContain(
|
||||
expect.$any([ activeClass, exactActiveClass ])
|
||||
)
|
||||
|
||||
await router.push('/route')
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).toBe('/route')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).not.toContain(
|
||||
expect.$any([ activeClass, exactActiveClass ])
|
||||
)
|
||||
|
||||
await router.push('/route/subRoute')
|
||||
|
||||
const cls = wrapper.get('a').classes()
|
||||
|
||||
expect(cls).toContain(activeClass)
|
||||
expect(cls).toContain(exactActiveClass)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)replace]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const testRoute = '/test-route'
|
||||
const router = await getRouter(testRoute)
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
replace: true
|
||||
},
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ to: testRoute })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('a').attributes('href')
|
||||
).toBe(testRoute)
|
||||
|
||||
const routerFn = vi.spyOn(router, 'replace')
|
||||
|
||||
await wrapper.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).toBe(testRoute)
|
||||
|
||||
expect(routerFn).toHaveBeenCalledTimes(1)
|
||||
expect(routerFn).toHaveBeenCalledWith(testRoute)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)active-class]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const activeClass = 'it-is-active'
|
||||
const router = await getRouter({ '/route': 'subRoute' })
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
activeClass
|
||||
},
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ to: '/route' })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('a').attributes('href')
|
||||
).toBe('/route')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).not.toContain(activeClass)
|
||||
|
||||
await router.push('/route')
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).toBe('/route')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).toContain(activeClass)
|
||||
|
||||
await router.push('/route/subRoute')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).toContain(activeClass)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)exact-active-class]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const exactActiveClass = 'it-is-exact-active'
|
||||
const router = await getRouter({
|
||||
'/route': { subRoute: 'other' }
|
||||
})
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
exact: true,
|
||||
exactActiveClass
|
||||
},
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ to: '/route/subRoute' })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('a').attributes('href')
|
||||
).toBe('/route/subRoute')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).not.toContain(exactActiveClass)
|
||||
|
||||
await router.push('/route')
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).toBe('/route')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).not.toContain(exactActiveClass)
|
||||
|
||||
await router.push('/route/subRoute')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).toContain(exactActiveClass)
|
||||
|
||||
await router.push('/route/subRoute/other')
|
||||
|
||||
expect(
|
||||
wrapper.get('a').classes()
|
||||
).not.toContain(exactActiveClass)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)href]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'https://quasar.dev'
|
||||
const wrapper = mount(QBreadcrumbsEl)
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ href: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('a').attributes('href')
|
||||
).toBe(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)target]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = '_blank'
|
||||
const href = 'https://quasar.dev'
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
target: propVal
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ href })
|
||||
await flushPromises()
|
||||
|
||||
const link = wrapper.get('a')
|
||||
|
||||
expect(
|
||||
link.attributes('href')
|
||||
).toBe(href)
|
||||
|
||||
expect(
|
||||
link.attributes('target')
|
||||
).toBe(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)disable]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const testRoute = '/home'
|
||||
const router = await getRouter(testRoute)
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
to: testRoute
|
||||
},
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(true)
|
||||
|
||||
await wrapper.setProps({ disable: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.find('a').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).not.toBe(testRoute)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)label]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'Home'
|
||||
const wrapper = mount(QBreadcrumbsEl)
|
||||
|
||||
expect(wrapper.text()).not.toContain(propVal)
|
||||
|
||||
await wrapper.setProps({ label: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.text()).toContain(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)icon]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'map'
|
||||
const wrapper = mount(QBreadcrumbsEl)
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-icon').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ icon: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-icon').text()
|
||||
).toContain(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)tag]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'div'
|
||||
const wrapper = mount(QBreadcrumbsEl)
|
||||
|
||||
expect(
|
||||
// default is 'span'
|
||||
wrapper.element.tagName
|
||||
).not.toBe(propVal.toUpperCase())
|
||||
|
||||
await wrapper.setProps({ tag: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.element.tagName
|
||||
).toBe(propVal.toUpperCase())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Slots]', () => {
|
||||
describe('[(slot)default]', () => {
|
||||
test('renders the content', () => {
|
||||
const slotContent = 'some-slot-content'
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
slots: {
|
||||
default: () => slotContent
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).toContain(slotContent)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Events]', () => {
|
||||
describe('[(event)click]', () => {
|
||||
test('is emitting without router', async () => {
|
||||
const wrapper = mount(QBreadcrumbsEl)
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).toHaveProperty('click')
|
||||
expect(eventList.click).toHaveLength(1)
|
||||
|
||||
const [ evt, go ] = eventList.click[ 0 ]
|
||||
expect(evt).toBeInstanceOf(Event)
|
||||
expect(go).not.toBeDefined()
|
||||
})
|
||||
|
||||
test('is emitting with router', async () => {
|
||||
const testRoute = '/home/dashboard'
|
||||
const router = await getRouter(testRoute)
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
to: testRoute
|
||||
},
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).toHaveProperty('click')
|
||||
expect(eventList.click).toHaveLength(1)
|
||||
|
||||
const [ evt, go ] = eventList.click[ 0 ]
|
||||
expect(evt).toBeInstanceOf(Event)
|
||||
expect(go).toBeTypeOf('function')
|
||||
})
|
||||
|
||||
test('does not navigates when prevented', async () => {
|
||||
const testRoute = '/home/dashboard'
|
||||
const router = await getRouter(testRoute)
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
to: testRoute,
|
||||
onClick: e => e.preventDefault()
|
||||
},
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).not.toBe(testRoute)
|
||||
})
|
||||
|
||||
test('can manually navigate by calling go()', async () => {
|
||||
const testRoute = '/home/dashboard'
|
||||
const router = await getRouter(testRoute)
|
||||
|
||||
const wrapper = mount(QBreadcrumbsEl, {
|
||||
props: {
|
||||
to: testRoute,
|
||||
onClick: (e, go) => {
|
||||
e.preventDefault()
|
||||
go()
|
||||
}
|
||||
},
|
||||
global: {
|
||||
plugins: [ router ]
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
router.currentRoute.value.path
|
||||
).toBe(testRoute)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
7
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/index.js
generated
vendored
Normal file
7
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import QBreadcrumbs from './QBreadcrumbs.js'
|
||||
import QBreadcrumbsEl from './QBreadcrumbsEl.js'
|
||||
|
||||
export {
|
||||
QBreadcrumbs,
|
||||
QBreadcrumbsEl
|
||||
}
|
||||
7
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/test/BasicBreadcrumbs.vue
generated
vendored
Normal file
7
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/test/BasicBreadcrumbs.vue
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<q-breadcrumbs v-bind="$attrs">
|
||||
<q-breadcrumbs-el label="Home" icon="home" />
|
||||
<q-breadcrumbs-el label="Components" icon="widgets" />
|
||||
<q-breadcrumbs-el label="Toolbar" />
|
||||
</q-breadcrumbs>
|
||||
</template>
|
||||
11
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/test/BreadcrumbWithSeparatorSlot.vue
generated
vendored
Normal file
11
Frontend-Learner/node_modules/quasar/src/components/breadcrumbs/test/BreadcrumbWithSeparatorSlot.vue
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<template>
|
||||
<q-breadcrumbs v-bind="$attrs">
|
||||
<q-breadcrumbs-el label="Home" icon="home" />
|
||||
<q-breadcrumbs-el label="Components" icon="widgets" />
|
||||
<q-breadcrumbs-el label="Toolbar" />
|
||||
|
||||
<template v-slot:separator>
|
||||
<q-icon size="1.2em" name="arrow_forward" color="purple" />
|
||||
</template>
|
||||
</q-breadcrumbs>
|
||||
</template>
|
||||
251
Frontend-Learner/node_modules/quasar/src/components/btn-dropdown/QBtnDropdown.js
generated
vendored
Normal file
251
Frontend-Learner/node_modules/quasar/src/components/btn-dropdown/QBtnDropdown.js
generated
vendored
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
import { h, ref, computed, watch, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
import QIcon from '../icon/QIcon.js'
|
||||
import QBtn from '../btn/QBtn.js'
|
||||
import QBtnGroup from '../btn-group/QBtnGroup.js'
|
||||
import QMenu from '../menu/QMenu.js'
|
||||
|
||||
import { getBtnDesignAttr, nonRoundBtnProps } from '../btn/use-btn.js'
|
||||
import useId from '../../composables/use-id/use-id.js'
|
||||
import { useTransitionProps } from '../../composables/private.use-transition/use-transition.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { stop } from '../../utils/event/event.js'
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
const btnPropsList = Object.keys(nonRoundBtnProps)
|
||||
|
||||
export function passBtnProps (props) {
|
||||
return btnPropsList.reduce((acc, key) => {
|
||||
const val = props[ key ]
|
||||
if (val !== void 0) {
|
||||
acc[ key ] = val
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBtnDropdown',
|
||||
|
||||
props: {
|
||||
...nonRoundBtnProps,
|
||||
...useTransitionProps,
|
||||
|
||||
modelValue: Boolean,
|
||||
split: Boolean,
|
||||
dropdownIcon: String,
|
||||
|
||||
contentClass: [ Array, String, Object ],
|
||||
contentStyle: [ Array, String, Object ],
|
||||
|
||||
cover: Boolean,
|
||||
persistent: Boolean,
|
||||
noEscDismiss: Boolean,
|
||||
noRouteDismiss: Boolean,
|
||||
autoClose: Boolean,
|
||||
noRefocus: Boolean,
|
||||
noFocus: Boolean,
|
||||
|
||||
menuAnchor: {
|
||||
type: String,
|
||||
default: 'bottom end'
|
||||
},
|
||||
menuSelf: {
|
||||
type: String,
|
||||
default: 'top end'
|
||||
},
|
||||
menuOffset: Array,
|
||||
|
||||
disableMainBtn: Boolean,
|
||||
disableDropdown: Boolean,
|
||||
|
||||
noIconAnimation: Boolean,
|
||||
|
||||
toggleAriaLabel: String
|
||||
},
|
||||
|
||||
emits: [ 'update:modelValue', 'click', 'beforeShow', 'show', 'beforeHide', 'hide' ],
|
||||
|
||||
setup (props, { slots, emit }) {
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const showing = ref(props.modelValue)
|
||||
const menuRef = ref(null)
|
||||
const targetUid = useId()
|
||||
|
||||
const ariaAttrs = computed(() => {
|
||||
const acc = {
|
||||
'aria-expanded': showing.value === true ? 'true' : 'false',
|
||||
'aria-haspopup': 'true',
|
||||
'aria-controls': targetUid.value,
|
||||
'aria-label': props.toggleAriaLabel || proxy.$q.lang.label[ showing.value === true ? 'collapse' : 'expand' ](props.label)
|
||||
}
|
||||
|
||||
if (
|
||||
props.disable === true
|
||||
|| (
|
||||
(props.split === false && props.disableMainBtn === true)
|
||||
|| props.disableDropdown === true
|
||||
)
|
||||
) {
|
||||
acc[ 'aria-disabled' ] = 'true'
|
||||
}
|
||||
|
||||
return acc
|
||||
})
|
||||
|
||||
const iconClass = computed(() =>
|
||||
'q-btn-dropdown__arrow'
|
||||
+ (showing.value === true && props.noIconAnimation === false ? ' rotate-180' : '')
|
||||
+ (props.split === false ? ' q-btn-dropdown__arrow-container' : '')
|
||||
)
|
||||
|
||||
const btnDesignAttr = computed(() => getBtnDesignAttr(props))
|
||||
const btnProps = computed(() => passBtnProps(props))
|
||||
|
||||
watch(() => props.modelValue, val => {
|
||||
menuRef.value?.[ val ? 'show' : 'hide' ]()
|
||||
})
|
||||
|
||||
watch(() => props.split, hide)
|
||||
|
||||
function onBeforeShow (e) {
|
||||
showing.value = true
|
||||
emit('beforeShow', e)
|
||||
}
|
||||
|
||||
function onShow (e) {
|
||||
emit('show', e)
|
||||
emit('update:modelValue', true)
|
||||
}
|
||||
|
||||
function onBeforeHide (e) {
|
||||
showing.value = false
|
||||
emit('beforeHide', e)
|
||||
}
|
||||
|
||||
function onHide (e) {
|
||||
emit('hide', e)
|
||||
emit('update:modelValue', false)
|
||||
}
|
||||
|
||||
function onClick (e) {
|
||||
emit('click', e)
|
||||
}
|
||||
|
||||
function onClickHide (e) {
|
||||
stop(e)
|
||||
hide()
|
||||
emit('click', e)
|
||||
}
|
||||
|
||||
function toggle (evt) {
|
||||
menuRef.value?.toggle(evt)
|
||||
}
|
||||
|
||||
function show (evt) {
|
||||
menuRef.value?.show(evt)
|
||||
}
|
||||
|
||||
function hide (evt) {
|
||||
menuRef.value?.hide(evt)
|
||||
}
|
||||
|
||||
// expose public methods
|
||||
Object.assign(proxy, {
|
||||
show, hide, toggle
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
props.modelValue === true && show()
|
||||
})
|
||||
|
||||
return () => {
|
||||
const Arrow = [
|
||||
h(QIcon, {
|
||||
class: iconClass.value,
|
||||
name: props.dropdownIcon || proxy.$q.iconSet.arrow.dropdown
|
||||
})
|
||||
]
|
||||
|
||||
props.disableDropdown !== true && Arrow.push(
|
||||
h(QMenu, {
|
||||
ref: menuRef,
|
||||
id: targetUid.value,
|
||||
class: props.contentClass,
|
||||
style: props.contentStyle,
|
||||
cover: props.cover,
|
||||
fit: true,
|
||||
persistent: props.persistent,
|
||||
noEscDismiss: props.noEscDismiss,
|
||||
noRouteDismiss: props.noRouteDismiss,
|
||||
autoClose: props.autoClose,
|
||||
noFocus: props.noFocus,
|
||||
noRefocus: props.noRefocus,
|
||||
anchor: props.menuAnchor,
|
||||
self: props.menuSelf,
|
||||
offset: props.menuOffset,
|
||||
separateClosePopup: true,
|
||||
transitionShow: props.transitionShow,
|
||||
transitionHide: props.transitionHide,
|
||||
transitionDuration: props.transitionDuration,
|
||||
onBeforeShow,
|
||||
onShow,
|
||||
onBeforeHide,
|
||||
onHide
|
||||
}, slots.default)
|
||||
)
|
||||
|
||||
if (props.split === false) {
|
||||
return h(QBtn, {
|
||||
class: 'q-btn-dropdown q-btn-dropdown--simple',
|
||||
...btnProps.value,
|
||||
...ariaAttrs.value,
|
||||
disable: props.disable === true || props.disableMainBtn === true,
|
||||
noWrap: true,
|
||||
round: false,
|
||||
onClick
|
||||
}, {
|
||||
default: () => hSlot(slots.label, []).concat(Arrow),
|
||||
loading: slots.loading
|
||||
})
|
||||
}
|
||||
|
||||
return h(QBtnGroup, {
|
||||
class: 'q-btn-dropdown q-btn-dropdown--split no-wrap q-btn-item',
|
||||
rounded: props.rounded,
|
||||
square: props.square,
|
||||
...btnDesignAttr.value,
|
||||
glossy: props.glossy,
|
||||
stretch: props.stretch
|
||||
}, () => [
|
||||
h(QBtn, {
|
||||
class: 'q-btn-dropdown--current',
|
||||
...btnProps.value,
|
||||
disable: props.disable === true || props.disableMainBtn === true,
|
||||
noWrap: true,
|
||||
round: false,
|
||||
onClick: onClickHide
|
||||
}, {
|
||||
default: slots.label,
|
||||
loading: slots.loading
|
||||
}),
|
||||
|
||||
h(QBtn, {
|
||||
class: 'q-btn-dropdown__arrow-container q-anchor--skip',
|
||||
...ariaAttrs.value,
|
||||
...btnDesignAttr.value,
|
||||
disable: props.disable === true || props.disableDropdown === true,
|
||||
rounded: props.rounded,
|
||||
color: props.color,
|
||||
textColor: props.textColor,
|
||||
dense: props.dense,
|
||||
size: props.size,
|
||||
padding: props.padding,
|
||||
ripple: props.ripple
|
||||
}, () => Arrow)
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
||||
170
Frontend-Learner/node_modules/quasar/src/components/btn-dropdown/QBtnDropdown.json
generated
vendored
Normal file
170
Frontend-Learner/node_modules/quasar/src/components/btn-dropdown/QBtnDropdown.json
generated
vendored
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
{
|
||||
"mixins": [ "components/btn/use-btn", "composables/private.use-model-toggle/use-model-toggle", "composables/private.use-transition/use-transition" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/button-dropdown"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"model-value": {
|
||||
"type": "Boolean",
|
||||
"__delete": [ "default" ]
|
||||
},
|
||||
|
||||
"split": {
|
||||
"type": "Boolean",
|
||||
"desc": "Split dropdown icon into its own button",
|
||||
"category": "content|behavior"
|
||||
},
|
||||
|
||||
"dropdown-icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"disable-main-btn": {
|
||||
"type": "Boolean",
|
||||
"desc": "Disable main button (useful along with 'split' prop)",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"disable-dropdown": {
|
||||
"type": "Boolean",
|
||||
"desc": "Disables dropdown (dropdown button if using along 'split' prop)",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"no-icon-animation": {
|
||||
"type": "Boolean",
|
||||
"desc": "Disables the rotation of the dropdown icon when state is toggled",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"content-style": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueStyleProp",
|
||||
"desc": "Style definitions to be attributed to the menu",
|
||||
"examples": [
|
||||
"'background-color: #ff0000'",
|
||||
"{ backgroundColor: '#ff0000' }"
|
||||
],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"content-class": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueClassProp",
|
||||
"desc": "Class definitions to be attributed to the menu",
|
||||
"examples": [
|
||||
"'my-special-class'",
|
||||
"{ 'my-special-class': true }"
|
||||
],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"cover": {
|
||||
"type": "Boolean",
|
||||
"desc": "Allows the menu to cover the button. When used, the 'menu-self' and 'menu-fit' props are no longer effective",
|
||||
"category": "position"
|
||||
},
|
||||
|
||||
"persistent": {
|
||||
"type": "Boolean",
|
||||
"desc": "Allows the menu to not be dismissed by a click/tap outside of the menu or by hitting the ESC key; Also, an app route change won't dismiss it",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"no-esc-dismiss": {
|
||||
"type": "Boolean",
|
||||
"desc": "User cannot dismiss the popup by hitting ESC key; No need to set it if 'persistent' prop is also set",
|
||||
"category": "behavior",
|
||||
"addedIn": "v2.18"
|
||||
},
|
||||
|
||||
"no-route-dismiss": {
|
||||
"type": "Boolean",
|
||||
"desc": "Changing route app won't dismiss the popup; No need to set it if 'persistent' prop is also set",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"auto-close": {
|
||||
"type": "Boolean",
|
||||
"desc": "Allows any click/tap in the menu to close it; Useful instead of attaching events to each menu item that should close the menu on click/tap",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"no-refocus": {
|
||||
"type": "Boolean",
|
||||
"desc": "(Accessibility) When the dropdown gets hidden, do not refocus on the DOM element that previously had focus",
|
||||
"category": "behavior",
|
||||
"addedIn": "v2.18"
|
||||
},
|
||||
|
||||
"no-focus": {
|
||||
"type": "Boolean",
|
||||
"desc": "(Accessibility) When the dropdown gets shown, do not switch focus on it",
|
||||
"category": "behavior",
|
||||
"addedIn": "v2.18"
|
||||
},
|
||||
|
||||
"menu-anchor": {
|
||||
"type": "String",
|
||||
"desc": "Two values setting the starting position or anchor point of the menu relative to its target",
|
||||
"values": [
|
||||
"'top left'", "'top middle'", "'top right'", "'top start'", "'top end'",
|
||||
"'center left'", "'center middle'", "'center right'", "'center start'", "'center end'",
|
||||
"'bottom left'", "'bottom middle'", "'bottom right'", "'bottom start'", "'bottom end'"
|
||||
],
|
||||
"default": "'bottom end'",
|
||||
"category": "position"
|
||||
},
|
||||
|
||||
"menu-self": {
|
||||
"type": "String",
|
||||
"desc": "Two values setting the menu's own position relative to its target",
|
||||
"values": [
|
||||
"'top left'", "'top middle'", "'top right'", "'top start'", "'top end'",
|
||||
"'center left'", "'center middle'", "'center right'", "'center start'", "'center end'",
|
||||
"'bottom left'", "'bottom middle'", "'bottom right'", "'bottom start'", "'bottom end'"
|
||||
],
|
||||
"default": "'top end'",
|
||||
"category": "position"
|
||||
},
|
||||
|
||||
"menu-offset": {
|
||||
"type": "Array",
|
||||
"desc": "An array of two numbers to offset the menu horizontally and vertically in pixels",
|
||||
"examples": [ "[ 8, 8 ]", "[ 5, 10 ]" ],
|
||||
"category": "position"
|
||||
},
|
||||
|
||||
"toggle-aria-label": {
|
||||
"type": "String",
|
||||
"desc": "aria-label to be used on the dropdown toggle element",
|
||||
"examples": [ "'Open menu'" ],
|
||||
"category": "accessibility",
|
||||
"addedIn": "v2.8.4"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"extends": "default"
|
||||
},
|
||||
|
||||
"label": {
|
||||
"desc": "Customize main button's content through this slot, unless you're using the 'icon' and 'label' props"
|
||||
},
|
||||
|
||||
"loading": {
|
||||
"desc": "Override the default QSpinner when in 'loading' state",
|
||||
"addedIn": "v2.8"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"click": {
|
||||
"extends": "click",
|
||||
"desc": "Emitted when user clicks/taps on the main button (not the icon one, if using 'split')"
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Frontend-Learner/node_modules/quasar/src/components/btn-dropdown/QBtnDropdown.sass
generated
vendored
Normal file
15
Frontend-Learner/node_modules/quasar/src/components/btn-dropdown/QBtnDropdown.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
.q-btn-dropdown
|
||||
&--split .q-btn-dropdown__arrow-container
|
||||
padding: 0 4px
|
||||
&.q-btn--outline
|
||||
border-left: 1px solid currentColor
|
||||
&:not(.q-btn--outline)
|
||||
border-left: 1px solid rgba(255,255,255,.3)
|
||||
|
||||
&--simple * + .q-btn-dropdown__arrow
|
||||
margin-left: 8px
|
||||
&__arrow
|
||||
transition: transform .28s
|
||||
|
||||
&--current
|
||||
flex-grow: 1
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/btn-dropdown/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/btn-dropdown/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QBtnDropdown from './QBtnDropdown.js'
|
||||
|
||||
export {
|
||||
QBtnDropdown
|
||||
}
|
||||
33
Frontend-Learner/node_modules/quasar/src/components/btn-group/QBtnGroup.js
generated
vendored
Normal file
33
Frontend-Learner/node_modules/quasar/src/components/btn-group/QBtnGroup.js
generated
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBtnGroup',
|
||||
|
||||
props: {
|
||||
unelevated: Boolean,
|
||||
outline: Boolean,
|
||||
flat: Boolean,
|
||||
rounded: Boolean,
|
||||
square: Boolean,
|
||||
push: Boolean,
|
||||
stretch: Boolean,
|
||||
glossy: Boolean,
|
||||
spread: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const classes = computed(() => {
|
||||
const cls = [ 'unelevated', 'outline', 'flat', 'rounded', 'square', 'push', 'stretch', 'glossy' ]
|
||||
.filter(t => props[ t ] === true)
|
||||
.map(t => `q-btn-group--${ t }`).join(' ')
|
||||
|
||||
return `q-btn-group row no-wrap${ cls.length !== 0 ? ' ' + cls : '' }`
|
||||
+ (props.spread === true ? ' q-btn-group--spread' : ' inline')
|
||||
})
|
||||
|
||||
return () => h('div', { class: classes.value }, hSlot(slots.default))
|
||||
}
|
||||
})
|
||||
66
Frontend-Learner/node_modules/quasar/src/components/btn-group/QBtnGroup.json
generated
vendored
Normal file
66
Frontend-Learner/node_modules/quasar/src/components/btn-group/QBtnGroup.json
generated
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/button-group"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"spread": {
|
||||
"type": "Boolean",
|
||||
"desc": "Spread horizontally to all available space",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"outline": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'outline' design for buttons",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"flat": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'flat' design for buttons",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"unelevated": {
|
||||
"type": "Boolean",
|
||||
"desc": "Remove shadow on buttons",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"rounded": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a more prominent border-radius for squared shape buttons",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"square": {
|
||||
"extends": "square",
|
||||
"addedIn": "v2.7.6"
|
||||
},
|
||||
|
||||
"push": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'push' design for buttons",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"stretch": {
|
||||
"type": "Boolean",
|
||||
"desc": "When used on flexbox parent, buttons will stretch to parent's height",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"glossy": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a glossy effect",
|
||||
"category": "style"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Suggestion: QBtn"
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Frontend-Learner/node_modules/quasar/src/components/btn-group/QBtnGroup.sass
generated
vendored
Normal file
88
Frontend-Learner/node_modules/quasar/src/components/btn-group/QBtnGroup.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
.q-btn-group
|
||||
border-radius: $button-border-radius
|
||||
box-shadow: $button-shadow
|
||||
vertical-align: middle
|
||||
|
||||
> .q-btn-item
|
||||
border-radius: inherit
|
||||
align-self: stretch
|
||||
|
||||
&:before
|
||||
box-shadow: none
|
||||
|
||||
.q-badge--floating
|
||||
right: 0
|
||||
|
||||
> .q-btn-group
|
||||
box-shadow: none
|
||||
|
||||
&:first-child
|
||||
> .q-btn:first-child
|
||||
border-top-left-radius: inherit
|
||||
border-bottom-left-radius: inherit
|
||||
&:last-child
|
||||
> .q-btn:last-child
|
||||
border-top-right-radius: inherit
|
||||
border-bottom-right-radius: inherit
|
||||
> .q-btn-group:not(:first-child) > .q-btn:first-child:before
|
||||
border-left: 0
|
||||
> .q-btn-group:not(:last-child) > .q-btn:last-child:before
|
||||
border-right: 0
|
||||
> .q-btn-item:not(:last-child)
|
||||
border-top-right-radius: 0
|
||||
border-bottom-right-radius: 0
|
||||
> .q-btn-item:not(:first-child)
|
||||
border-top-left-radius: 0
|
||||
border-bottom-left-radius: 0
|
||||
> .q-btn-item.q-btn--standard:before
|
||||
z-index: -1
|
||||
|
||||
&--push
|
||||
border-radius: $button-push-border-radius
|
||||
|
||||
> .q-btn--push
|
||||
&.q-btn--actionable
|
||||
transform: none
|
||||
|
||||
.q-btn__content
|
||||
transition: margin-top $button-transition, margin-bottom $button-transition
|
||||
|
||||
&:active,
|
||||
&.q-btn--active
|
||||
.q-btn__content
|
||||
margin-top: 2px
|
||||
margin-bottom: -2px
|
||||
|
||||
&--rounded
|
||||
border-radius: $button-rounded-border-radius
|
||||
|
||||
&--square
|
||||
border-radius: 0
|
||||
|
||||
&--flat, &--outline, &--unelevated
|
||||
box-shadow: none
|
||||
|
||||
&--outline
|
||||
> .q-separator
|
||||
display: none
|
||||
> .q-btn-item + .q-btn-item:before
|
||||
border-left: 0
|
||||
> .q-btn-item:not(:last-child):before
|
||||
border-right: 0
|
||||
|
||||
&--stretch
|
||||
align-self: stretch
|
||||
border-radius: 0
|
||||
|
||||
&--glossy
|
||||
> .q-btn-item
|
||||
background-image: linear-gradient(to bottom, rgba(#fff, .3), rgba(#fff, 0) 50%, rgba(#000, .12) 51%, rgba(#000, .04)) !important
|
||||
|
||||
&--spread
|
||||
> .q-btn-group
|
||||
display: flex !important
|
||||
> .q-btn-item, > .q-btn-group > .q-btn-item:not(.q-btn-dropdown__arrow-container)
|
||||
width: auto
|
||||
min-width: 0
|
||||
max-width: 100%
|
||||
flex: 10000 1 0%
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/btn-group/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/btn-group/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QBtnGroup from './QBtnGroup.js'
|
||||
|
||||
export {
|
||||
QBtnGroup
|
||||
}
|
||||
169
Frontend-Learner/node_modules/quasar/src/components/btn-toggle/QBtnToggle.js
generated
vendored
Normal file
169
Frontend-Learner/node_modules/quasar/src/components/btn-toggle/QBtnToggle.js
generated
vendored
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import QBtn from '../btn/QBtn.js'
|
||||
import QBtnGroup from '../btn-group/QBtnGroup.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { useFormInject, useFormProps } from '../../composables/use-form/private.use-form.js'
|
||||
|
||||
import { hMergeSlot } from '../../utils/private.render/render.js'
|
||||
import { getBtnDesignAttr } from '../btn/use-btn.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBtnToggle',
|
||||
|
||||
props: {
|
||||
...useFormProps,
|
||||
|
||||
modelValue: {
|
||||
required: true
|
||||
},
|
||||
|
||||
options: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: v => v.every(
|
||||
opt => ('label' in opt || 'icon' in opt || 'slot' in opt) && 'value' in opt
|
||||
)
|
||||
},
|
||||
|
||||
// To avoid seeing the active raise shadow through
|
||||
// the transparent button, give it a color (even white)
|
||||
color: String,
|
||||
textColor: String,
|
||||
toggleColor: {
|
||||
type: String,
|
||||
default: 'primary'
|
||||
},
|
||||
toggleTextColor: String,
|
||||
|
||||
outline: Boolean,
|
||||
flat: Boolean,
|
||||
unelevated: Boolean,
|
||||
rounded: Boolean,
|
||||
push: Boolean,
|
||||
glossy: Boolean,
|
||||
|
||||
size: String,
|
||||
padding: String,
|
||||
|
||||
noCaps: Boolean,
|
||||
noWrap: Boolean,
|
||||
dense: Boolean,
|
||||
readonly: Boolean,
|
||||
disable: Boolean,
|
||||
|
||||
stack: Boolean,
|
||||
stretch: Boolean,
|
||||
|
||||
spread: Boolean,
|
||||
|
||||
clearable: Boolean,
|
||||
|
||||
ripple: {
|
||||
type: [ Boolean, Object ],
|
||||
default: true
|
||||
}
|
||||
},
|
||||
|
||||
emits: [ 'update:modelValue', 'clear', 'click' ],
|
||||
|
||||
setup (props, { slots, emit }) {
|
||||
const hasActiveValue = computed(() =>
|
||||
props.options.find(opt => opt.value === props.modelValue) !== void 0
|
||||
)
|
||||
|
||||
const formAttrs = computed(() => ({
|
||||
type: 'hidden',
|
||||
name: props.name,
|
||||
value: props.modelValue
|
||||
}))
|
||||
|
||||
const injectFormInput = useFormInject(formAttrs)
|
||||
|
||||
const btnDesignAttr = computed(() => getBtnDesignAttr(props))
|
||||
|
||||
const btnOptionDesign = computed(() => ({
|
||||
rounded: props.rounded,
|
||||
dense: props.dense,
|
||||
...btnDesignAttr.value
|
||||
}))
|
||||
|
||||
const btnOptions = computed(() => props.options.map((item, i) => {
|
||||
const { attrs, value, slot, ...opt } = item
|
||||
|
||||
return {
|
||||
slot,
|
||||
props: {
|
||||
key: i,
|
||||
|
||||
'aria-pressed': value === props.modelValue ? 'true' : 'false',
|
||||
...attrs,
|
||||
...opt,
|
||||
...btnOptionDesign.value,
|
||||
|
||||
disable: props.disable === true || opt.disable === true,
|
||||
|
||||
// Options that come from the button specific options first, then from general props
|
||||
color: value === props.modelValue
|
||||
? mergeOpt(opt, 'toggleColor')
|
||||
: mergeOpt(opt, 'color'),
|
||||
textColor: value === props.modelValue
|
||||
? mergeOpt(opt, 'toggleTextColor')
|
||||
: mergeOpt(opt, 'textColor'),
|
||||
noCaps: mergeOpt(opt, 'noCaps') === true,
|
||||
noWrap: mergeOpt(opt, 'noWrap') === true,
|
||||
|
||||
size: mergeOpt(opt, 'size'),
|
||||
padding: mergeOpt(opt, 'padding'),
|
||||
ripple: mergeOpt(opt, 'ripple'),
|
||||
stack: mergeOpt(opt, 'stack') === true,
|
||||
stretch: mergeOpt(opt, 'stretch') === true,
|
||||
|
||||
onClick (e) { set(value, item, e) }
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
function set (value, opt, e) {
|
||||
if (props.readonly !== true) {
|
||||
if (props.modelValue === value) {
|
||||
if (props.clearable === true) {
|
||||
emit('update:modelValue', null, null)
|
||||
emit('clear')
|
||||
}
|
||||
}
|
||||
else {
|
||||
emit('update:modelValue', value, opt)
|
||||
}
|
||||
|
||||
emit('click', e)
|
||||
}
|
||||
}
|
||||
|
||||
function mergeOpt (opt, key) {
|
||||
return opt[ key ] === void 0 ? props[ key ] : opt[ key ]
|
||||
}
|
||||
|
||||
function getContent () {
|
||||
const child = btnOptions.value.map(opt => {
|
||||
return h(QBtn, opt.props, opt.slot !== void 0 ? slots[ opt.slot ] : void 0)
|
||||
})
|
||||
|
||||
if (props.name !== void 0 && props.disable !== true && hasActiveValue.value === true) {
|
||||
injectFormInput(child, 'push')
|
||||
}
|
||||
|
||||
return hMergeSlot(slots.default, child)
|
||||
}
|
||||
|
||||
return () => h(QBtnGroup, {
|
||||
class: 'q-btn-toggle',
|
||||
...btnDesignAttr.value,
|
||||
rounded: props.rounded,
|
||||
stretch: props.stretch,
|
||||
glossy: props.glossy,
|
||||
spread: props.spread
|
||||
}, getContent)
|
||||
}
|
||||
})
|
||||
197
Frontend-Learner/node_modules/quasar/src/components/btn-toggle/QBtnToggle.json
generated
vendored
Normal file
197
Frontend-Learner/node_modules/quasar/src/components/btn-toggle/QBtnToggle.json
generated
vendored
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
{
|
||||
"mixins": [ "composables/use-form/private.use-form" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/button-toggle"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"model-value": {
|
||||
"extends": "model-value",
|
||||
"type": "Any",
|
||||
"desc": "Model of the component; Either use this property (along with a listener for 'update:modelValue' event) OR use v-model directive",
|
||||
"examples": [ "# v-model=\"selected\"" ]
|
||||
},
|
||||
|
||||
"options": {
|
||||
"type": "Array",
|
||||
"desc": "Array of Objects defining each option",
|
||||
"required": true,
|
||||
"definition": {
|
||||
"attrs": {
|
||||
"type": "Object",
|
||||
"desc": "Key-value for attributes to be set on the button",
|
||||
"examples": [ "{ 'aria-label': 'Button label' }" ],
|
||||
"__exemption": [ "definition" ]
|
||||
},
|
||||
"label": {
|
||||
"type": "String",
|
||||
"desc": "Label of option button; Use this prop and/or 'icon', but at least one is required",
|
||||
"examples": [ "'Option 1'" ]
|
||||
},
|
||||
"icon": {
|
||||
"extends": "icon",
|
||||
"desc": "Icon of option button; Use this prop and/or 'label', but at least one is required"
|
||||
},
|
||||
"value": {
|
||||
"type": "Any",
|
||||
"desc": "Value of the option that will be used by component model",
|
||||
"required": true
|
||||
},
|
||||
"slot": {
|
||||
"type": "String",
|
||||
"desc": "Slot name to use for this button content; Useful for customizing content or even add tooltips",
|
||||
"examples": [ "'mySlot'" ]
|
||||
},
|
||||
"...props": {
|
||||
"type": "Any",
|
||||
"desc": "Any other QBtn props (including class and style)"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
"[ { label: 'One', value: 'one' }, { label: 'Two', value: 'two' } ]"
|
||||
],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"text-color": {
|
||||
"extends": "text-color"
|
||||
},
|
||||
|
||||
"toggle-color": {
|
||||
"extends": "color",
|
||||
"default": "'primary'"
|
||||
},
|
||||
|
||||
"toggle-text-color": {
|
||||
"extends": "text-color"
|
||||
},
|
||||
|
||||
"spread": {
|
||||
"type": "Boolean",
|
||||
"desc": "Spread horizontally to all available space",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"outline": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'outline' design",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"flat": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'flat' design",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"unelevated": {
|
||||
"type": "Boolean",
|
||||
"desc": "Remove shadow",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"rounded": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a more prominent border-radius for a squared shape button",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"push": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'push' design",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"glossy": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a glossy effect",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"size": {
|
||||
"type": "String",
|
||||
"desc": "Button size name or a CSS unit including unit name",
|
||||
"examples": [ "'xs'", "'sm'", "'md'", "'lg'", "'xl'", "'25px'", "'2rem'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"padding": {
|
||||
"type": "String",
|
||||
"desc": "Apply custom padding (vertical [horizontal]); Size in CSS units, including unit name or standard size name (none|xs|sm|md|lg|xl); Also removes the min width and height when set",
|
||||
"examples": [ "'16px'", "'10px 5px'", "'2rem'", "'xs'", "'md lg'", "'2px 2px 5px 7px'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"no-caps": {
|
||||
"type": "Boolean",
|
||||
"desc": "Avoid turning label text into caps (which happens by default)",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"no-wrap": {
|
||||
"type": "Boolean",
|
||||
"desc": "Avoid label text wrapping",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"ripple": {
|
||||
"extends": "ripple"
|
||||
},
|
||||
|
||||
"dense": {
|
||||
"extends": "dense"
|
||||
},
|
||||
|
||||
"readonly": {
|
||||
"extends": "readonly"
|
||||
},
|
||||
|
||||
"disable": {
|
||||
"extends": "disable"
|
||||
},
|
||||
|
||||
"stack": {
|
||||
"type": "Boolean",
|
||||
"desc": "Stack icon and label vertically instead of on same line (like it is by default)",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"stretch": {
|
||||
"type": "Boolean",
|
||||
"desc": "When used on flexbox parent, button will stretch to parent's height",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"clearable": {
|
||||
"type": "Boolean",
|
||||
"desc": "Clears model on click of the already selected button",
|
||||
"category": "model"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"update:model-value": {
|
||||
"extends": "update:model-value"
|
||||
},
|
||||
|
||||
"clear": {
|
||||
"desc": "When using the 'clearable' property, this event is emitted when the already selected button is clicked"
|
||||
},
|
||||
|
||||
"click": { "internal": true }
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Suggestions: QTooltip, QBadge"
|
||||
},
|
||||
"...": {
|
||||
"desc": "Any other dynamic slots to be used with 'slot' property of the 'options' prop"
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Frontend-Learner/node_modules/quasar/src/components/btn-toggle/QBtnToggle.sass
generated
vendored
Normal file
2
Frontend-Learner/node_modules/quasar/src/components/btn-toggle/QBtnToggle.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
.q-btn-toggle
|
||||
position: relative
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/btn-toggle/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/btn-toggle/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QBtnToggle from './QBtnToggle.js'
|
||||
|
||||
export {
|
||||
QBtnToggle
|
||||
}
|
||||
382
Frontend-Learner/node_modules/quasar/src/components/btn/QBtn.js
generated
vendored
Normal file
382
Frontend-Learner/node_modules/quasar/src/components/btn/QBtn.js
generated
vendored
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
import { h, ref, computed, Transition, onBeforeUnmount, withDirectives, getCurrentInstance } from 'vue'
|
||||
|
||||
import QIcon from '../icon/QIcon.js'
|
||||
import QSpinner from '../spinner/QSpinner.js'
|
||||
|
||||
import Ripple from '../../directives/ripple/Ripple.js'
|
||||
|
||||
import useBtn, { useBtnProps } from './use-btn.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hMergeSlot } from '../../utils/private.render/render.js'
|
||||
import { stop, prevent, stopAndPrevent, listenOpts } from '../../utils/event/event.js'
|
||||
import { isKeyCode } from '../../utils/private.keyboard/key-composition.js'
|
||||
|
||||
const { passiveCapture } = listenOpts
|
||||
|
||||
let
|
||||
touchTarget = null,
|
||||
keyboardTarget = null,
|
||||
mouseTarget = null
|
||||
|
||||
export default createComponent({
|
||||
name: 'QBtn',
|
||||
|
||||
props: {
|
||||
...useBtnProps,
|
||||
|
||||
percentage: Number,
|
||||
darkPercentage: Boolean,
|
||||
|
||||
onTouchstart: [ Function, Array ]
|
||||
},
|
||||
|
||||
emits: [ 'click', 'keydown', 'mousedown', 'keyup' ],
|
||||
|
||||
setup (props, { slots, emit }) {
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const {
|
||||
classes, style, innerClasses,
|
||||
attributes,
|
||||
hasLink, linkTag, navigateOnClick,
|
||||
isActionable
|
||||
} = useBtn(props)
|
||||
|
||||
const rootRef = ref(null)
|
||||
const blurTargetRef = ref(null)
|
||||
|
||||
let localTouchTargetEl = null, avoidMouseRipple, mouseTimer = null
|
||||
|
||||
const hasLabel = computed(() =>
|
||||
props.label !== void 0 && props.label !== null && props.label !== ''
|
||||
)
|
||||
|
||||
const ripple = computed(() => (
|
||||
props.disable === true || props.ripple === false
|
||||
? false
|
||||
: {
|
||||
keyCodes: hasLink.value === true ? [ 13, 32 ] : [ 13 ],
|
||||
...(props.ripple === true ? {} : props.ripple)
|
||||
}
|
||||
))
|
||||
|
||||
const rippleProps = computed(() => ({ center: props.round }))
|
||||
|
||||
const percentageStyle = computed(() => {
|
||||
const val = Math.max(0, Math.min(100, props.percentage))
|
||||
return val > 0
|
||||
? { transition: 'transform 0.6s', transform: `translateX(${ val - 100 }%)` }
|
||||
: {}
|
||||
})
|
||||
|
||||
const onEvents = computed(() => {
|
||||
if (props.loading === true) {
|
||||
return {
|
||||
onMousedown: onLoadingEvt,
|
||||
onTouchstart: onLoadingEvt,
|
||||
onClick: onLoadingEvt,
|
||||
onKeydown: onLoadingEvt,
|
||||
onKeyup: onLoadingEvt
|
||||
}
|
||||
}
|
||||
|
||||
if (isActionable.value === true) {
|
||||
const acc = {
|
||||
onClick,
|
||||
onKeydown,
|
||||
onMousedown
|
||||
}
|
||||
|
||||
if (proxy.$q.platform.has.touch === true) {
|
||||
const suffix = props.onTouchstart !== void 0
|
||||
? ''
|
||||
: 'Passive'
|
||||
|
||||
acc[ `onTouchstart${ suffix }` ] = onTouchstart
|
||||
}
|
||||
|
||||
return acc
|
||||
}
|
||||
|
||||
return {
|
||||
// needed; especially for disabled <a> tags
|
||||
onClick: stopAndPrevent
|
||||
}
|
||||
})
|
||||
|
||||
const nodeProps = computed(() => ({
|
||||
ref: rootRef,
|
||||
class: 'q-btn q-btn-item non-selectable no-outline ' + classes.value,
|
||||
style: style.value,
|
||||
...attributes.value,
|
||||
...onEvents.value
|
||||
}))
|
||||
|
||||
function onClick (e) {
|
||||
// is it already destroyed?
|
||||
if (rootRef.value === null) return
|
||||
|
||||
if (e !== void 0) {
|
||||
if (e.defaultPrevented === true) return
|
||||
|
||||
const el = document.activeElement
|
||||
// focus button if it came from ENTER on form
|
||||
// prevent the new submit (already done)
|
||||
if (
|
||||
props.type === 'submit'
|
||||
&& el !== document.body
|
||||
&& rootRef.value.contains(el) === false
|
||||
// required for iOS and desktop Safari
|
||||
&& el.contains(rootRef.value) === false
|
||||
) {
|
||||
e.qAvoidFocus !== true && rootRef.value.focus()
|
||||
|
||||
const onClickCleanup = () => {
|
||||
document.removeEventListener('keydown', stopAndPrevent, true)
|
||||
document.removeEventListener('keyup', onClickCleanup, passiveCapture)
|
||||
rootRef.value?.removeEventListener('blur', onClickCleanup, passiveCapture)
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', stopAndPrevent, true)
|
||||
document.addEventListener('keyup', onClickCleanup, passiveCapture)
|
||||
rootRef.value.addEventListener('blur', onClickCleanup, passiveCapture)
|
||||
}
|
||||
}
|
||||
|
||||
navigateOnClick(e)
|
||||
}
|
||||
|
||||
function onKeydown (e) {
|
||||
// is it already destroyed?
|
||||
if (rootRef.value === null) return
|
||||
|
||||
emit('keydown', e)
|
||||
|
||||
if (isKeyCode(e, [ 13, 32 ]) === true && keyboardTarget !== rootRef.value) {
|
||||
keyboardTarget !== null && cleanup()
|
||||
|
||||
if (e.defaultPrevented !== true) {
|
||||
// focus external button if the focus helper was focused before
|
||||
e.qAvoidFocus !== true && rootRef.value.focus()
|
||||
|
||||
keyboardTarget = rootRef.value
|
||||
rootRef.value.classList.add('q-btn--active')
|
||||
document.addEventListener('keyup', onPressEnd, true)
|
||||
rootRef.value.addEventListener('blur', onPressEnd, passiveCapture)
|
||||
}
|
||||
|
||||
stopAndPrevent(e)
|
||||
}
|
||||
}
|
||||
|
||||
function onTouchstart (e) {
|
||||
// is it already destroyed?
|
||||
if (rootRef.value === null) return
|
||||
|
||||
emit('touchstart', e)
|
||||
|
||||
if (e.defaultPrevented === true) return
|
||||
|
||||
if (touchTarget !== rootRef.value) {
|
||||
touchTarget !== null && cleanup()
|
||||
touchTarget = rootRef.value
|
||||
|
||||
localTouchTargetEl = e.target
|
||||
localTouchTargetEl.addEventListener('touchcancel', onPressEnd, passiveCapture)
|
||||
localTouchTargetEl.addEventListener('touchend', onPressEnd, passiveCapture)
|
||||
}
|
||||
|
||||
// avoid duplicated mousedown event
|
||||
// triggering another early ripple
|
||||
avoidMouseRipple = true
|
||||
mouseTimer !== null && clearTimeout(mouseTimer)
|
||||
mouseTimer = setTimeout(() => {
|
||||
mouseTimer = null
|
||||
avoidMouseRipple = false
|
||||
}, 200)
|
||||
}
|
||||
|
||||
function onMousedown (e) {
|
||||
// is it already destroyed?
|
||||
if (rootRef.value === null) return
|
||||
|
||||
e.qSkipRipple = avoidMouseRipple === true
|
||||
emit('mousedown', e)
|
||||
|
||||
if (e.defaultPrevented !== true && mouseTarget !== rootRef.value) {
|
||||
mouseTarget !== null && cleanup()
|
||||
mouseTarget = rootRef.value
|
||||
rootRef.value.classList.add('q-btn--active')
|
||||
document.addEventListener('mouseup', onPressEnd, passiveCapture)
|
||||
}
|
||||
}
|
||||
|
||||
function onPressEnd (e) {
|
||||
// is it already destroyed?
|
||||
if (rootRef.value === null) return
|
||||
|
||||
// needed for IE (because it emits blur when focusing button from focus helper)
|
||||
if (
|
||||
e?.type === 'blur'
|
||||
&& document.activeElement === rootRef.value
|
||||
) return
|
||||
|
||||
if (e?.type === 'keyup') {
|
||||
if (keyboardTarget === rootRef.value && isKeyCode(e, [ 13, 32 ]) === true) {
|
||||
// for click trigger
|
||||
const evt = new MouseEvent('click', e)
|
||||
evt.qKeyEvent = true
|
||||
e.defaultPrevented === true && prevent(evt)
|
||||
e.cancelBubble === true && stop(evt)
|
||||
rootRef.value.dispatchEvent(evt)
|
||||
|
||||
stopAndPrevent(e)
|
||||
|
||||
// for ripple
|
||||
e.qKeyEvent = true
|
||||
}
|
||||
|
||||
emit('keyup', e)
|
||||
}
|
||||
|
||||
cleanup()
|
||||
}
|
||||
|
||||
function cleanup (destroying) {
|
||||
const blurTarget = blurTargetRef.value
|
||||
|
||||
if (
|
||||
destroying !== true
|
||||
&& (touchTarget === rootRef.value || mouseTarget === rootRef.value)
|
||||
&& blurTarget !== null
|
||||
&& blurTarget !== document.activeElement
|
||||
) {
|
||||
blurTarget.setAttribute('tabindex', -1)
|
||||
blurTarget.focus()
|
||||
}
|
||||
|
||||
if (touchTarget === rootRef.value) {
|
||||
if (localTouchTargetEl !== null) {
|
||||
localTouchTargetEl.removeEventListener('touchcancel', onPressEnd, passiveCapture)
|
||||
localTouchTargetEl.removeEventListener('touchend', onPressEnd, passiveCapture)
|
||||
}
|
||||
touchTarget = localTouchTargetEl = null
|
||||
}
|
||||
|
||||
if (mouseTarget === rootRef.value) {
|
||||
document.removeEventListener('mouseup', onPressEnd, passiveCapture)
|
||||
mouseTarget = null
|
||||
}
|
||||
|
||||
if (keyboardTarget === rootRef.value) {
|
||||
document.removeEventListener('keyup', onPressEnd, true)
|
||||
rootRef.value?.removeEventListener('blur', onPressEnd, passiveCapture)
|
||||
keyboardTarget = null
|
||||
}
|
||||
|
||||
rootRef.value?.classList.remove('q-btn--active')
|
||||
}
|
||||
|
||||
function onLoadingEvt (evt) {
|
||||
stopAndPrevent(evt)
|
||||
evt.qSkipRipple = true
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
cleanup(true)
|
||||
})
|
||||
|
||||
// expose public methods
|
||||
Object.assign(proxy, {
|
||||
click: e => {
|
||||
if (isActionable.value === true) {
|
||||
onClick(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
let inner = []
|
||||
|
||||
props.icon !== void 0 && inner.push(
|
||||
h(QIcon, {
|
||||
name: props.icon,
|
||||
left: props.stack !== true && hasLabel.value === true,
|
||||
role: 'img'
|
||||
})
|
||||
)
|
||||
|
||||
hasLabel.value === true && inner.push(
|
||||
h('span', { class: 'block' }, [ props.label ])
|
||||
)
|
||||
|
||||
inner = hMergeSlot(slots.default, inner)
|
||||
|
||||
if (props.iconRight !== void 0 && props.round === false) {
|
||||
inner.push(
|
||||
h(QIcon, {
|
||||
name: props.iconRight,
|
||||
right: props.stack !== true && hasLabel.value === true,
|
||||
role: 'img'
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const child = [
|
||||
h('span', {
|
||||
class: 'q-focus-helper',
|
||||
ref: blurTargetRef
|
||||
})
|
||||
]
|
||||
|
||||
if (props.loading === true && props.percentage !== void 0) {
|
||||
child.push(
|
||||
h('span', {
|
||||
class: 'q-btn__progress absolute-full overflow-hidden' + (props.darkPercentage === true ? ' q-btn__progress--dark' : '')
|
||||
}, [
|
||||
h('span', {
|
||||
class: 'q-btn__progress-indicator fit block',
|
||||
style: percentageStyle.value
|
||||
})
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
child.push(
|
||||
h('span', {
|
||||
class: 'q-btn__content text-center col items-center q-anchor--skip ' + innerClasses.value
|
||||
}, inner)
|
||||
)
|
||||
|
||||
props.loading !== null && child.push(
|
||||
h(Transition, {
|
||||
name: 'q-transition--fade'
|
||||
}, () => (
|
||||
props.loading === true
|
||||
? [
|
||||
h('span', {
|
||||
key: 'loading',
|
||||
class: 'absolute-full flex flex-center'
|
||||
}, slots.loading !== void 0 ? slots.loading() : [ h(QSpinner) ])
|
||||
]
|
||||
: null
|
||||
))
|
||||
)
|
||||
|
||||
return withDirectives(
|
||||
h(
|
||||
linkTag.value,
|
||||
nodeProps.value,
|
||||
child
|
||||
),
|
||||
[ [
|
||||
Ripple,
|
||||
ripple.value,
|
||||
void 0,
|
||||
rippleProps.value
|
||||
] ]
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
106
Frontend-Learner/node_modules/quasar/src/components/btn/QBtn.json
generated
vendored
Normal file
106
Frontend-Learner/node_modules/quasar/src/components/btn/QBtn.json
generated
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
{
|
||||
"mixins": [ "components/btn/use-btn" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/button"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"round": {
|
||||
"type": "Boolean",
|
||||
"desc": "Makes a circle shaped button",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"percentage": {
|
||||
"type": "Number",
|
||||
"desc": "Percentage (0.0 < x < 100.0); To be used along 'loading' prop; Display a progress bar on the background",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"dark-percentage": {
|
||||
"type": "Boolean",
|
||||
"desc": "Progress bar on the background should have dark color; To be used along with 'percentage' and 'loading' props",
|
||||
"category": "behavior"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Use for custom content, instead of relying on 'icon' and 'label' props"
|
||||
},
|
||||
|
||||
"loading": {
|
||||
"desc": "Override the default QSpinner when in 'loading' state"
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"click": {
|
||||
"desc": "Emulate click on QBtn",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt"
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"click": {
|
||||
"desc": "Emitted when the component is clicked",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"desc": "JS event object; If you are using route navigation ('to'/'replace' props) and you want to cancel navigation then call evt.preventDefault() synchronously in your event handler"
|
||||
},
|
||||
"go": {
|
||||
"type": "Function",
|
||||
"desc": "Available ONLY if you are using route navigation ('to'/'replace' props); When you need to control the time at which the component should trigger the route navigation then call evt.preventDefault() synchronously and then call this function at your convenience; Useful if you have async work to be done before the actual route navigation or if you want to redirect somewhere else",
|
||||
"required": false,
|
||||
"addedIn": "v2.9",
|
||||
"params": {
|
||||
"opts": {
|
||||
"type": "Object",
|
||||
"desc": "Optional options",
|
||||
"required": false,
|
||||
"definition": {
|
||||
"to": {
|
||||
"type": [ "String", "Object" ],
|
||||
"desc": "Equivalent to Vue Router <router-link> 'to' property; Specify it explicitly otherwise it will be set with same value as component's 'to' prop",
|
||||
"required": false,
|
||||
"examples": [
|
||||
"'/home/dashboard'",
|
||||
"{ name: 'my-route-name' }"
|
||||
]
|
||||
},
|
||||
|
||||
"replace": {
|
||||
"type": "Boolean",
|
||||
"desc": "Equivalent to Vue Router <router-link> 'replace' property; Specify it explicitly otherwise it will be set with same value as component's 'replace' prop",
|
||||
"required": false
|
||||
},
|
||||
|
||||
"returnRouterError": {
|
||||
"type": "Boolean",
|
||||
"desc": "Return the router error, if any; Otherwise the returned Promise will always fulfill",
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Promise<any>",
|
||||
"desc": "Returns the router's navigation promise"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"touchstart": { "internal": true },
|
||||
"keydown": { "internal": true },
|
||||
"keyup": { "internal": true },
|
||||
"mousedown": { "internal": true }
|
||||
}
|
||||
}
|
||||
159
Frontend-Learner/node_modules/quasar/src/components/btn/QBtn.sass
generated
vendored
Normal file
159
Frontend-Learner/node_modules/quasar/src/components/btn/QBtn.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
.q-btn
|
||||
display: inline-flex
|
||||
flex-direction: column
|
||||
align-items: stretch
|
||||
position: relative
|
||||
outline: 0
|
||||
border: 0
|
||||
vertical-align: middle
|
||||
font-size: $button-font-size
|
||||
line-height: $button-line-height
|
||||
text-decoration: none
|
||||
color: inherit
|
||||
background: transparent
|
||||
font-weight: $button-font-weight
|
||||
text-transform: uppercase
|
||||
text-align: center
|
||||
width: auto
|
||||
height: auto
|
||||
cursor: default
|
||||
padding: $button-padding
|
||||
min-height: 2.572em
|
||||
|
||||
.q-icon, .q-spinner
|
||||
font-size: $button-line-height
|
||||
|
||||
&.disabled
|
||||
opacity: .7 !important
|
||||
|
||||
&:before
|
||||
content: ''
|
||||
display: block
|
||||
position: absolute
|
||||
left: 0
|
||||
right: 0
|
||||
top: 0
|
||||
bottom: 0
|
||||
border-radius: inherit
|
||||
box-shadow: $button-shadow
|
||||
|
||||
&--actionable
|
||||
cursor: pointer
|
||||
|
||||
&.q-btn--standard
|
||||
&:before
|
||||
// This places the button active raise shadow behind adjacent elements
|
||||
// Active raise shadow will still be visible under adjacent transparent elements, this is ok and coherent with a desired transparency effect.
|
||||
// Visible active raise shadow can be removed by specifying a background color to the button
|
||||
// Visible active raise shadow can be removed by specifying a flat or outline button type
|
||||
transition: box-shadow $button-transition
|
||||
&:active,
|
||||
&.q-btn--active
|
||||
&:before
|
||||
box-shadow: $button-shadow-active
|
||||
|
||||
&--no-uppercase
|
||||
text-transform: none
|
||||
|
||||
&--rectangle
|
||||
border-radius: $button-border-radius
|
||||
|
||||
&--outline
|
||||
background: transparent !important
|
||||
|
||||
&:before
|
||||
border: 1px solid currentColor
|
||||
|
||||
&--push
|
||||
border-radius: $button-push-border-radius
|
||||
|
||||
&:before
|
||||
border-bottom: 3px solid rgba(0,0,0,.15)
|
||||
|
||||
&.q-btn--actionable
|
||||
transition: transform $button-transition
|
||||
|
||||
&:before
|
||||
transition: border-width $button-transition
|
||||
|
||||
&:active,
|
||||
&.q-btn--active
|
||||
transform: translateY(2px)
|
||||
|
||||
&:before
|
||||
border-bottom-width: 0
|
||||
|
||||
&--rounded
|
||||
border-radius: $button-rounded-border-radius
|
||||
|
||||
&--round
|
||||
border-radius: 50%
|
||||
|
||||
padding: 0
|
||||
min-width: 3em
|
||||
min-height: 3em
|
||||
|
||||
&--square
|
||||
border-radius: 0
|
||||
|
||||
&--flat, &--outline, &--unelevated
|
||||
&:before
|
||||
box-shadow: none
|
||||
|
||||
&--dense
|
||||
padding: $button-dense-padding
|
||||
min-height: 2em
|
||||
|
||||
&.q-btn--round
|
||||
padding: 0
|
||||
min-height: 2.4em
|
||||
min-width: 2.4em
|
||||
|
||||
.on-left
|
||||
margin-right: 6px
|
||||
|
||||
.on-right
|
||||
margin-left: 6px
|
||||
|
||||
&--fab, &--fab-mini
|
||||
.q-icon
|
||||
font-size: $button-fab-icon-font-size
|
||||
|
||||
&--fab
|
||||
padding: 16px
|
||||
min-height: 56px
|
||||
min-width: 56px
|
||||
|
||||
.q-icon
|
||||
margin: auto
|
||||
|
||||
&--fab-mini
|
||||
padding: 8px
|
||||
min-height: 40px
|
||||
min-width: 40px
|
||||
|
||||
// workaround for alignment/sizing change when showing loader
|
||||
&__content
|
||||
transition: opacity .3s
|
||||
z-index: 0
|
||||
|
||||
&--hidden
|
||||
opacity: 0
|
||||
pointer-events: none
|
||||
|
||||
&__progress
|
||||
border-radius: inherit
|
||||
z-index: 0
|
||||
|
||||
&-indicator
|
||||
z-index: -1
|
||||
transform: translateX(-100%)
|
||||
background: rgba(255,255,255,.25)
|
||||
&--dark
|
||||
.q-btn__progress-indicator
|
||||
background: rgba(0,0,0,.2)
|
||||
|
||||
&--flat, &--outline
|
||||
.q-btn__progress-indicator
|
||||
opacity: 0.2
|
||||
background: currentColor
|
||||
1386
Frontend-Learner/node_modules/quasar/src/components/btn/QBtn.test.js
generated
vendored
Normal file
1386
Frontend-Learner/node_modules/quasar/src/components/btn/QBtn.test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
5
Frontend-Learner/node_modules/quasar/src/components/btn/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/btn/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QBtn from './QBtn.js'
|
||||
|
||||
export {
|
||||
QBtn
|
||||
}
|
||||
225
Frontend-Learner/node_modules/quasar/src/components/btn/use-btn.js
generated
vendored
Normal file
225
Frontend-Learner/node_modules/quasar/src/components/btn/use-btn.js
generated
vendored
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
import { computed } from 'vue'
|
||||
|
||||
import useAlign, { useAlignProps } from '../../composables/private.use-align/use-align.js'
|
||||
import useSize, { useSizeProps } from '../../composables/private.use-size/use-size.js'
|
||||
import useRouterLink, { useRouterLinkNonMatchingProps } from '../../composables/private.use-router-link/use-router-link.js'
|
||||
|
||||
export const btnPadding = {
|
||||
none: 0,
|
||||
xs: 4,
|
||||
sm: 8,
|
||||
md: 16,
|
||||
lg: 24,
|
||||
xl: 32
|
||||
}
|
||||
|
||||
export const defaultSizes = {
|
||||
xs: 8,
|
||||
sm: 10,
|
||||
md: 14,
|
||||
lg: 20,
|
||||
xl: 24
|
||||
}
|
||||
|
||||
const formTypes = [ 'button', 'submit', 'reset' ]
|
||||
const mediaTypeRE = /[^\s]\/[^\s]/
|
||||
|
||||
export const btnDesignOptions = [ 'flat', 'outline', 'push', 'unelevated' ]
|
||||
|
||||
export function getBtnDesign (props, defaultValue) {
|
||||
if (props.flat === true) return 'flat'
|
||||
if (props.outline === true) return 'outline'
|
||||
if (props.push === true) return 'push'
|
||||
if (props.unelevated === true) return 'unelevated'
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
export function getBtnDesignAttr (props) {
|
||||
const design = getBtnDesign(props)
|
||||
return design !== void 0
|
||||
? { [ design ]: true }
|
||||
: {}
|
||||
}
|
||||
|
||||
export const nonRoundBtnProps = {
|
||||
...useSizeProps,
|
||||
...useRouterLinkNonMatchingProps,
|
||||
|
||||
type: {
|
||||
type: String,
|
||||
default: 'button'
|
||||
},
|
||||
|
||||
label: [ Number, String ],
|
||||
icon: String,
|
||||
iconRight: String,
|
||||
|
||||
...btnDesignOptions.reduce(
|
||||
(acc, val) => (acc[ val ] = Boolean) && acc,
|
||||
{}
|
||||
),
|
||||
|
||||
square: Boolean,
|
||||
rounded: Boolean,
|
||||
glossy: Boolean,
|
||||
|
||||
size: String,
|
||||
fab: Boolean,
|
||||
fabMini: Boolean,
|
||||
padding: String,
|
||||
|
||||
color: String,
|
||||
textColor: String,
|
||||
noCaps: Boolean,
|
||||
noWrap: Boolean,
|
||||
dense: Boolean,
|
||||
|
||||
tabindex: [ Number, String ],
|
||||
|
||||
ripple: {
|
||||
type: [ Boolean, Object ],
|
||||
default: true
|
||||
},
|
||||
|
||||
align: {
|
||||
...useAlignProps.align,
|
||||
default: 'center'
|
||||
},
|
||||
stack: Boolean,
|
||||
stretch: Boolean,
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
disable: Boolean
|
||||
}
|
||||
|
||||
export const useBtnProps = {
|
||||
...nonRoundBtnProps,
|
||||
round: Boolean
|
||||
}
|
||||
|
||||
export default function (props) {
|
||||
const sizeStyle = useSize(props, defaultSizes)
|
||||
const alignClass = useAlign(props)
|
||||
const { hasRouterLink, hasLink, linkTag, linkAttrs, navigateOnClick } = useRouterLink({
|
||||
fallbackTag: 'button'
|
||||
})
|
||||
|
||||
const style = computed(() => {
|
||||
const obj = props.fab === false && props.fabMini === false
|
||||
? sizeStyle.value
|
||||
: {}
|
||||
|
||||
return props.padding !== void 0
|
||||
? Object.assign({}, obj, {
|
||||
padding: props.padding
|
||||
.split(/\s+/)
|
||||
.map(v => (v in btnPadding ? btnPadding[ v ] + 'px' : v))
|
||||
.join(' '),
|
||||
minWidth: '0',
|
||||
minHeight: '0'
|
||||
})
|
||||
: obj
|
||||
})
|
||||
|
||||
const isRounded = computed(() =>
|
||||
props.rounded === true || props.fab === true || props.fabMini === true
|
||||
)
|
||||
|
||||
const isActionable = computed(() =>
|
||||
props.disable !== true && props.loading !== true
|
||||
)
|
||||
|
||||
const tabIndex = computed(() => (
|
||||
isActionable.value === true ? props.tabindex || 0 : -1
|
||||
))
|
||||
|
||||
const design = computed(() => getBtnDesign(props, 'standard'))
|
||||
|
||||
const attributes = computed(() => {
|
||||
const acc = { tabindex: tabIndex.value }
|
||||
|
||||
if (hasLink.value === true) {
|
||||
Object.assign(acc, linkAttrs.value)
|
||||
}
|
||||
else if (formTypes.includes(props.type) === true) {
|
||||
acc.type = props.type
|
||||
}
|
||||
|
||||
if (linkTag.value === 'a') {
|
||||
if (props.disable === true) {
|
||||
acc[ 'aria-disabled' ] = 'true'
|
||||
}
|
||||
else if (acc.href === void 0) {
|
||||
acc.role = 'button'
|
||||
}
|
||||
|
||||
if (hasRouterLink.value !== true && mediaTypeRE.test(props.type) === true) {
|
||||
acc.type = props.type
|
||||
}
|
||||
}
|
||||
else if (props.disable === true) {
|
||||
acc.disabled = ''
|
||||
acc[ 'aria-disabled' ] = 'true'
|
||||
}
|
||||
|
||||
if (props.loading === true && props.percentage !== void 0) {
|
||||
Object.assign(acc, {
|
||||
role: 'progressbar',
|
||||
'aria-valuemin': 0,
|
||||
'aria-valuemax': 100,
|
||||
'aria-valuenow': props.percentage
|
||||
})
|
||||
}
|
||||
|
||||
return acc
|
||||
})
|
||||
|
||||
const classes = computed(() => {
|
||||
let colors
|
||||
|
||||
if (props.color !== void 0) {
|
||||
if (props.flat === true || props.outline === true) {
|
||||
colors = `text-${ props.textColor || props.color }`
|
||||
}
|
||||
else {
|
||||
colors = `bg-${ props.color } text-${ props.textColor || 'white' }`
|
||||
}
|
||||
}
|
||||
else if (props.textColor) {
|
||||
colors = `text-${ props.textColor }`
|
||||
}
|
||||
|
||||
const shape = props.round === true
|
||||
? 'round'
|
||||
: `rectangle${ isRounded.value === true ? ' q-btn--rounded' : (props.square === true ? ' q-btn--square' : '') }`
|
||||
|
||||
return `q-btn--${ design.value } q-btn--${ shape }`
|
||||
+ (colors !== void 0 ? ' ' + colors : '')
|
||||
+ (isActionable.value === true ? ' q-btn--actionable q-focusable q-hoverable' : (props.disable === true ? ' disabled' : ''))
|
||||
+ (props.fab === true ? ' q-btn--fab' : (props.fabMini === true ? ' q-btn--fab-mini' : ''))
|
||||
+ (props.noCaps === true ? ' q-btn--no-uppercase' : '')
|
||||
+ (props.dense === true ? ' q-btn--dense' : '')
|
||||
+ (props.stretch === true ? ' no-border-radius self-stretch' : '')
|
||||
+ (props.glossy === true ? ' glossy' : '')
|
||||
+ (props.square ? ' q-btn--square' : '')
|
||||
})
|
||||
|
||||
const innerClasses = computed(() =>
|
||||
alignClass.value + (props.stack === true ? ' column' : ' row')
|
||||
+ (props.noWrap === true ? ' no-wrap text-no-wrap' : '')
|
||||
+ (props.loading === true ? ' q-btn__content--hidden' : '')
|
||||
)
|
||||
|
||||
return {
|
||||
classes,
|
||||
style,
|
||||
innerClasses,
|
||||
attributes,
|
||||
hasLink,
|
||||
linkTag,
|
||||
navigateOnClick,
|
||||
isActionable
|
||||
}
|
||||
}
|
||||
187
Frontend-Learner/node_modules/quasar/src/components/btn/use-btn.json
generated
vendored
Normal file
187
Frontend-Learner/node_modules/quasar/src/components/btn/use-btn.json
generated
vendored
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
{
|
||||
"mixins": [ "composables/private.use-size/use-size" ],
|
||||
|
||||
"props": {
|
||||
"type":{
|
||||
"type": "String",
|
||||
"desc": "1) Define the button native type attribute (submit, reset, button) or 2) render component with <a> tag so you can access events even if disable or 3) Use 'href' prop and specify 'type' as a media tag",
|
||||
"default": "'button'",
|
||||
"examples": [
|
||||
"'a'", "'submit'", "'button'", "'reset'",
|
||||
"'image/png'",
|
||||
"# href=\"https://quasar.dev\" target=\"_blank\""
|
||||
],
|
||||
"category": "general"
|
||||
},
|
||||
|
||||
"to": {
|
||||
"type": [ "String", "Object" ],
|
||||
"desc": "Equivalent to Vue Router <router-link> 'to' property; Superseded by 'href' prop if used",
|
||||
"examples": [
|
||||
"'/home/dashboard'",
|
||||
"{ name: 'my-route-name' }"
|
||||
],
|
||||
"category": "navigation"
|
||||
},
|
||||
|
||||
"replace": {
|
||||
"type": "Boolean",
|
||||
"desc": "Equivalent to Vue Router <router-link> 'replace' property; Superseded by 'href' prop if used",
|
||||
"category": "navigation"
|
||||
},
|
||||
|
||||
"href": {
|
||||
"type": "String",
|
||||
"desc": "Native <a> link href attribute; Has priority over the 'to' and 'replace' props",
|
||||
"examples": [ "'https://quasar.dev'", "# href=\"https://quasar.dev\" target=\"_blank\"" ],
|
||||
"category": "navigation",
|
||||
"addedIn": "v2.4"
|
||||
},
|
||||
|
||||
"target": {
|
||||
"type": "String",
|
||||
"desc": "Native <a> link target attribute; Use it only with 'to' or 'href' props",
|
||||
"examples": [ "'_blank'", "'_self'", "'_parent'", "'_top'" ],
|
||||
"category": "navigation",
|
||||
"addedIn": "v2.4"
|
||||
},
|
||||
|
||||
"label":{
|
||||
"type": [ "String", "Number" ],
|
||||
"desc": "The text that will be shown on the button",
|
||||
"examples": [ "'Button Label'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"icon-right": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"outline": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'outline' design",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"flat": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'flat' design",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"unelevated": {
|
||||
"type": "Boolean",
|
||||
"desc": "Remove shadow",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"rounded": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a more prominent border-radius for a squared shape button",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"push": {
|
||||
"type": "Boolean",
|
||||
"desc": "Use 'push' design",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"square": {
|
||||
"extends": "square",
|
||||
"addedIn": "v2.7.6"
|
||||
},
|
||||
|
||||
"glossy": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a glossy effect",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"fab": {
|
||||
"type": "Boolean",
|
||||
"desc": "Makes button size and shape to fit a Floating Action Button",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"fab-mini": {
|
||||
"type": "Boolean",
|
||||
"desc": "Makes button size and shape to fit a small Floating Action Button",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"padding": {
|
||||
"type": "String",
|
||||
"desc": "Apply custom padding (vertical [horizontal]); Size in CSS units, including unit name or standard size name (none|xs|sm|md|lg|xl); Also removes the min width and height when set",
|
||||
"examples": [ "'16px'", "'10px 5px'", "'2rem'", "'xs'", "'md lg'", "'2px 2px 5px 7px'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"text-color": {
|
||||
"extends": "text-color"
|
||||
},
|
||||
|
||||
"no-caps": {
|
||||
"type": "Boolean",
|
||||
"desc": "Avoid turning label text into caps (which happens by default)",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"no-wrap": {
|
||||
"type": "Boolean",
|
||||
"desc": "Avoid label text wrapping",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"dense": {
|
||||
"extends": "dense"
|
||||
},
|
||||
|
||||
"ripple": {
|
||||
"extends": "ripple"
|
||||
},
|
||||
|
||||
"tabindex": {
|
||||
"extends": "tabindex"
|
||||
},
|
||||
|
||||
"align": {
|
||||
"type": "String",
|
||||
"desc": "Label or content alignment",
|
||||
"default": "'center'",
|
||||
"values": [ "'left'", "'right'", "'center'", "'around'", "'between'", "'evenly'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"stack": {
|
||||
"type": "Boolean",
|
||||
"desc": "Stack icon and label vertically instead of on same line (like it is by default)",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"stretch": {
|
||||
"type": "Boolean",
|
||||
"desc": "When used on flexbox parent, button will stretch to parent's height",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"loading": {
|
||||
"type": [ "Boolean", "null" ],
|
||||
"default": "null",
|
||||
"desc": "Put button into loading state (displays a QSpinner -- can be overridden by using a 'loading' slot)",
|
||||
"category": "behavior|state"
|
||||
},
|
||||
|
||||
"disable": {
|
||||
"extends": "disable"
|
||||
}
|
||||
}
|
||||
}
|
||||
142
Frontend-Learner/node_modules/quasar/src/components/btn/use-btn.test.js
generated
vendored
Normal file
142
Frontend-Learner/node_modules/quasar/src/components/btn/use-btn.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import { mount } from '@vue/test-utils'
|
||||
import { describe, test, expect } from 'vitest'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import useBtn, {
|
||||
btnPadding, defaultSizes, btnDesignOptions,
|
||||
useBtnProps, nonRoundBtnProps,
|
||||
getBtnDesign, getBtnDesignAttr
|
||||
} from './use-btn.js'
|
||||
|
||||
describe('[useBtn API]', () => {
|
||||
describe('[Variables]', () => {
|
||||
describe('[(variable)btnPadding]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(btnPadding).toBeTypeOf('object')
|
||||
expect(Object.keys(btnPadding)).not.toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(variable)defaultSizes]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(defaultSizes).toBeTypeOf('object')
|
||||
expect(Object.keys(defaultSizes)).not.toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(variable)btnDesignOptions]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(btnDesignOptions).toBeTypeOf('object')
|
||||
expect(Object.keys(btnDesignOptions)).not.toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(variable)useBtnProps]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(useBtnProps).toBeTypeOf('object')
|
||||
expect(Object.keys(useBtnProps)).not.toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(variable)nonRoundBtnProps]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(nonRoundBtnProps).toBeTypeOf('object')
|
||||
expect(Object.keys(nonRoundBtnProps)).not.toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Functions]', () => {
|
||||
describe('[(function)default]', () => {
|
||||
test('has correct return value', () => {
|
||||
const wrapper = mount(
|
||||
defineComponent({
|
||||
template: '<div />',
|
||||
setup () {
|
||||
const result = useBtn({})
|
||||
return { result }
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
expect(
|
||||
wrapper.vm.result
|
||||
).toStrictEqual({
|
||||
classes: expect.$ref(expect.any(String)),
|
||||
style: expect.$ref(expect.any(Object)),
|
||||
innerClasses: expect.$ref(expect.any(String)),
|
||||
attributes: expect.$ref(expect.any(Object)),
|
||||
hasLink: expect.$ref(expect.any(Boolean)),
|
||||
linkTag: expect.$ref(expect.any(String)),
|
||||
navigateOnClick: expect.any(Function),
|
||||
isActionable: expect.$ref(expect.any(Boolean))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(function)getBtnDesign]', () => {
|
||||
test('returns correctly with single value', () => {
|
||||
for (const prop of btnDesignOptions) {
|
||||
expect(
|
||||
getBtnDesign({ [ prop ]: true })
|
||||
).toBe(prop)
|
||||
|
||||
expect(
|
||||
getBtnDesign({ [ prop ]: true }, 'default')
|
||||
).toBe(prop)
|
||||
|
||||
expect(
|
||||
getBtnDesign({ [ prop ]: false })
|
||||
).toBeUndefined()
|
||||
|
||||
expect(
|
||||
getBtnDesign({ [ prop ]: false }, 'default')
|
||||
).toBe('default')
|
||||
}
|
||||
})
|
||||
|
||||
test('returns correctly with multiple values', () => {
|
||||
for (const prop of btnDesignOptions) {
|
||||
const propMap = btnDesignOptions
|
||||
.reduce((acc, val) => {
|
||||
if (val !== prop) {
|
||||
acc[ val ] = true
|
||||
}
|
||||
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
expect(
|
||||
getBtnDesign(propMap)
|
||||
).not.toBe(prop)
|
||||
|
||||
expect(
|
||||
getBtnDesign(propMap, 'default')
|
||||
).not.toBe('default')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(function)getBtnDesignAttr]', () => {
|
||||
test('has correct return value', () => {
|
||||
expect(
|
||||
getBtnDesignAttr({})
|
||||
).toStrictEqual({})
|
||||
|
||||
expect(
|
||||
getBtnDesignAttr({ something: true })
|
||||
).toStrictEqual({})
|
||||
|
||||
for (const prop of btnDesignOptions) {
|
||||
expect(
|
||||
getBtnDesignAttr({ [ prop ]: true })
|
||||
).toStrictEqual({ [ prop ]: true })
|
||||
|
||||
expect(
|
||||
getBtnDesignAttr({ [ prop ]: false })
|
||||
).toStrictEqual({})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
38
Frontend-Learner/node_modules/quasar/src/components/card/QCard.js
generated
vendored
Normal file
38
Frontend-Learner/node_modules/quasar/src/components/card/QCard.js
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { h, computed, getCurrentInstance } from 'vue'
|
||||
|
||||
import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QCard',
|
||||
|
||||
props: {
|
||||
...useDarkProps,
|
||||
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
},
|
||||
|
||||
square: Boolean,
|
||||
flat: Boolean,
|
||||
bordered: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const { proxy: { $q } } = getCurrentInstance()
|
||||
const isDark = useDark(props, $q)
|
||||
|
||||
const classes = computed(() =>
|
||||
'q-card'
|
||||
+ (isDark.value === true ? ' q-card--dark q-dark' : '')
|
||||
+ (props.bordered === true ? ' q-card--bordered' : '')
|
||||
+ (props.square === true ? ' q-card--square no-border-radius' : '')
|
||||
+ (props.flat === true ? ' q-card--flat no-shadow' : '')
|
||||
)
|
||||
|
||||
return () => h(props.tag, { class: classes.value }, hSlot(slots.default))
|
||||
}
|
||||
})
|
||||
35
Frontend-Learner/node_modules/quasar/src/components/card/QCard.json
generated
vendored
Normal file
35
Frontend-Learner/node_modules/quasar/src/components/card/QCard.json
generated
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/card"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"dark": {
|
||||
"extends": "dark"
|
||||
},
|
||||
|
||||
"square": {
|
||||
"extends": "square"
|
||||
},
|
||||
|
||||
"flat": {
|
||||
"extends": "flat"
|
||||
},
|
||||
|
||||
"bordered": {
|
||||
"extends": "bordered"
|
||||
},
|
||||
|
||||
"tag": {
|
||||
"extends": "tag",
|
||||
"default": "'div'",
|
||||
"examples": [ "'div'", "'form'" ]
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"extends": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
90
Frontend-Learner/node_modules/quasar/src/components/card/QCard.sass
generated
vendored
Normal file
90
Frontend-Learner/node_modules/quasar/src/components/card/QCard.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
.q-card
|
||||
box-shadow: $shadow-2
|
||||
border-radius: $generic-border-radius
|
||||
vertical-align: top
|
||||
background: #fff
|
||||
position: relative
|
||||
|
||||
> div,
|
||||
> img
|
||||
&:not(.q--avoid-card-border)
|
||||
border-top-left-radius: 0
|
||||
border-top-right-radius: 0
|
||||
border-bottom-left-radius: 0
|
||||
border-bottom-right-radius: 0
|
||||
&:nth-child(1 of :not(.q--avoid-card-border))
|
||||
border-top: 0
|
||||
border-top-left-radius: inherit
|
||||
border-top-right-radius: inherit
|
||||
&:nth-last-child(1 of :not(.q--avoid-card-border))
|
||||
border-bottom: 0
|
||||
border-bottom-left-radius: inherit
|
||||
border-bottom-right-radius: inherit
|
||||
|
||||
> div:not(.q--avoid-card-border)
|
||||
border-left: 0
|
||||
border-right: 0
|
||||
box-shadow: none
|
||||
|
||||
&--bordered
|
||||
border: 1px solid $separator-color
|
||||
|
||||
&--dark
|
||||
border-color: $separator-dark-color
|
||||
box-shadow: $dark-shadow-2
|
||||
|
||||
&__section
|
||||
position: relative
|
||||
|
||||
&--vert
|
||||
padding: 16px
|
||||
|
||||
&--horiz
|
||||
> div,
|
||||
> img
|
||||
&:not(.q--avoid-card-border)
|
||||
border-top-left-radius: 0
|
||||
border-bottom-left-radius: 0
|
||||
border-top-right-radius: 0
|
||||
border-bottom-right-radius: 0
|
||||
&:nth-child(1 of :not(.q--avoid-card-border))
|
||||
border-top-left-radius: inherit
|
||||
border-bottom-left-radius: inherit
|
||||
&:nth-last-child(1 of :not(.q--avoid-card-border))
|
||||
border-top-right-radius: inherit
|
||||
border-bottom-right-radius: inherit
|
||||
|
||||
> div:not(.q--avoid-card-border)
|
||||
border-top: 0
|
||||
border-bottom: 0
|
||||
box-shadow: none
|
||||
|
||||
&__actions
|
||||
padding: 8px
|
||||
align-items: center
|
||||
|
||||
.q-btn--rectangle
|
||||
padding: 0 8px
|
||||
|
||||
&--horiz
|
||||
> .q-btn-item + .q-btn-item,
|
||||
> .q-btn-group + .q-btn-item,
|
||||
> .q-btn-item + .q-btn-group
|
||||
margin-left: 8px
|
||||
|
||||
&--vert
|
||||
> .q-btn-item.q-btn--round
|
||||
align-self: center
|
||||
> .q-btn-item + .q-btn-item,
|
||||
> .q-btn-group + .q-btn-item,
|
||||
> .q-btn-item + .q-btn-group
|
||||
margin-top: 4px
|
||||
|
||||
> .q-btn-group > .q-btn-item
|
||||
flex-grow: 1
|
||||
|
||||
> img
|
||||
display: block
|
||||
width: 100%
|
||||
max-width: 100%
|
||||
border: 0
|
||||
26
Frontend-Learner/node_modules/quasar/src/components/card/QCardActions.js
generated
vendored
Normal file
26
Frontend-Learner/node_modules/quasar/src/components/card/QCardActions.js
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import useAlign, { useAlignProps } from '../../composables/private.use-align/use-align.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QCardActions',
|
||||
|
||||
props: {
|
||||
...useAlignProps,
|
||||
vertical: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const alignClass = useAlign(props)
|
||||
|
||||
const classes = computed(() =>
|
||||
`q-card__actions ${ alignClass.value }`
|
||||
+ ` q-card__actions--${ props.vertical === true ? 'vert column' : 'horiz row' }`
|
||||
)
|
||||
|
||||
return () => h('div', { class: classes.value }, hSlot(slots.default))
|
||||
}
|
||||
})
|
||||
28
Frontend-Learner/node_modules/quasar/src/components/card/QCardActions.json
generated
vendored
Normal file
28
Frontend-Learner/node_modules/quasar/src/components/card/QCardActions.json
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/card"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"align": {
|
||||
"type": "String",
|
||||
"desc": "Specify how to align the actions; For horizontal mode, the default is 'left', while for vertical mode, the default is 'stretch'",
|
||||
"default": "# 'left'/'stretch'",
|
||||
"__runtimeDefault": true,
|
||||
"values": [ "'left'", "'center'", "'right'", "'between'", "'around'", "'evenly'", "'stretch'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"vertical": {
|
||||
"type": "Boolean",
|
||||
"desc": "Display actions one below the other",
|
||||
"category": "content"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Suggestions: QBtn"
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Frontend-Learner/node_modules/quasar/src/components/card/QCardSection.js
generated
vendored
Normal file
26
Frontend-Learner/node_modules/quasar/src/components/card/QCardSection.js
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QCardSection',
|
||||
|
||||
props: {
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
},
|
||||
|
||||
horizontal: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const classes = computed(() =>
|
||||
'q-card__section'
|
||||
+ ` q-card__section--${ props.horizontal === true ? 'horiz row no-wrap' : 'vert' }`
|
||||
)
|
||||
|
||||
return () => h(props.tag, { class: classes.value }, hSlot(slots.default))
|
||||
}
|
||||
})
|
||||
25
Frontend-Learner/node_modules/quasar/src/components/card/QCardSection.json
generated
vendored
Normal file
25
Frontend-Learner/node_modules/quasar/src/components/card/QCardSection.json
generated
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/card"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"horizontal": {
|
||||
"type": "Boolean",
|
||||
"desc": "Display a horizontal section (will have no padding and can contain other QCardSection)",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"tag": {
|
||||
"extends": "tag",
|
||||
"default": "'div'",
|
||||
"examples": [ "'div'", "'form'" ]
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"extends": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
Frontend-Learner/node_modules/quasar/src/components/card/index.js
generated
vendored
Normal file
9
Frontend-Learner/node_modules/quasar/src/components/card/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import QCard from './QCard.js'
|
||||
import QCardSection from './QCardSection.js'
|
||||
import QCardActions from './QCardActions.js'
|
||||
|
||||
export {
|
||||
QCard,
|
||||
QCardSection,
|
||||
QCardActions
|
||||
}
|
||||
283
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarousel.js
generated
vendored
Normal file
283
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarousel.js
generated
vendored
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
import { h, computed, watch, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue'
|
||||
|
||||
import QBtn from '../btn/QBtn.js'
|
||||
|
||||
import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js'
|
||||
import usePanel, { usePanelProps, usePanelEmits } from '../../composables/private.use-panel/use-panel.js'
|
||||
import useFullscreen, { useFullscreenProps, useFullscreenEmits } from '../../composables/private.use-fullscreen/use-fullscreen.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { isNumber } from '../../utils/is/is.js'
|
||||
import { hMergeSlot, hDir } from '../../utils/private.render/render.js'
|
||||
|
||||
const navigationPositionOptions = [ 'top', 'right', 'bottom', 'left' ]
|
||||
const controlTypeOptions = [ 'regular', 'flat', 'outline', 'push', 'unelevated' ]
|
||||
|
||||
export default createComponent({
|
||||
name: 'QCarousel',
|
||||
|
||||
props: {
|
||||
...useDarkProps,
|
||||
...usePanelProps,
|
||||
...useFullscreenProps,
|
||||
|
||||
transitionPrev: { // usePanelParentProps override
|
||||
type: String,
|
||||
default: 'fade'
|
||||
},
|
||||
transitionNext: { // usePanelParentProps override
|
||||
type: String,
|
||||
default: 'fade'
|
||||
},
|
||||
|
||||
height: String,
|
||||
padding: Boolean,
|
||||
|
||||
controlColor: String,
|
||||
controlTextColor: String,
|
||||
controlType: {
|
||||
type: String,
|
||||
validator: v => controlTypeOptions.includes(v),
|
||||
default: 'flat'
|
||||
},
|
||||
|
||||
autoplay: [ Number, Boolean ],
|
||||
|
||||
arrows: Boolean,
|
||||
prevIcon: String,
|
||||
nextIcon: String,
|
||||
|
||||
navigation: Boolean,
|
||||
navigationPosition: {
|
||||
type: String,
|
||||
validator: v => navigationPositionOptions.includes(v)
|
||||
},
|
||||
navigationIcon: String,
|
||||
navigationActiveIcon: String,
|
||||
|
||||
thumbnails: Boolean
|
||||
},
|
||||
|
||||
emits: [
|
||||
...useFullscreenEmits,
|
||||
...usePanelEmits
|
||||
],
|
||||
|
||||
setup (props, { slots }) {
|
||||
const { proxy: { $q } } = getCurrentInstance()
|
||||
|
||||
const isDark = useDark(props, $q)
|
||||
|
||||
let timer = null, panelsLen
|
||||
|
||||
const {
|
||||
updatePanelsList, getPanelContent,
|
||||
panelDirectives, goToPanel,
|
||||
previousPanel, nextPanel, getEnabledPanels,
|
||||
panelIndex
|
||||
} = usePanel()
|
||||
|
||||
const { inFullscreen } = useFullscreen()
|
||||
|
||||
const style = computed(() => (
|
||||
inFullscreen.value !== true && props.height !== void 0
|
||||
? { height: props.height }
|
||||
: {}
|
||||
))
|
||||
|
||||
const direction = computed(() => (props.vertical === true ? 'vertical' : 'horizontal'))
|
||||
|
||||
const navigationPosition = computed(() => props.navigationPosition
|
||||
|| (props.vertical === true ? 'right' : 'bottom')
|
||||
)
|
||||
|
||||
const classes = computed(() =>
|
||||
`q-carousel q-panel-parent q-carousel--with${ props.padding === true ? '' : 'out' }-padding`
|
||||
+ (inFullscreen.value === true ? ' fullscreen' : '')
|
||||
+ (isDark.value === true ? ' q-carousel--dark q-dark' : '')
|
||||
+ (props.arrows === true ? ` q-carousel--arrows-${ direction.value }` : '')
|
||||
+ (props.navigation === true ? ` q-carousel--navigation-${ navigationPosition.value }` : '')
|
||||
)
|
||||
|
||||
const arrowIcons = computed(() => {
|
||||
const ico = [
|
||||
props.prevIcon || $q.iconSet.carousel[ props.vertical === true ? 'up' : 'left' ],
|
||||
props.nextIcon || $q.iconSet.carousel[ props.vertical === true ? 'down' : 'right' ]
|
||||
]
|
||||
|
||||
return props.vertical === false && $q.lang.rtl === true
|
||||
? ico.reverse()
|
||||
: ico
|
||||
})
|
||||
|
||||
const navIcon = computed(() => props.navigationIcon || $q.iconSet.carousel.navigationIcon)
|
||||
const navActiveIcon = computed(() => props.navigationActiveIcon || navIcon.value)
|
||||
|
||||
const controlProps = computed(() => ({
|
||||
color: props.controlColor,
|
||||
textColor: props.controlTextColor,
|
||||
round: true,
|
||||
[ props.controlType ]: true,
|
||||
dense: true
|
||||
}))
|
||||
|
||||
watch(() => props.modelValue, () => {
|
||||
if (props.autoplay) {
|
||||
startTimer()
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.autoplay, val => {
|
||||
if (val) {
|
||||
startTimer()
|
||||
}
|
||||
else if (timer !== null) {
|
||||
clearTimeout(timer)
|
||||
timer = null
|
||||
}
|
||||
})
|
||||
|
||||
function startTimer () {
|
||||
const duration = isNumber(props.autoplay) === true
|
||||
? Math.abs(props.autoplay)
|
||||
: 5000
|
||||
|
||||
timer !== null && clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
|
||||
if (duration >= 0) {
|
||||
nextPanel()
|
||||
}
|
||||
else {
|
||||
previousPanel()
|
||||
}
|
||||
}, duration)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
props.autoplay && startTimer()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
timer !== null && clearTimeout(timer)
|
||||
})
|
||||
|
||||
function getNavigationContainer (type, mapping) {
|
||||
return h('div', {
|
||||
class: 'q-carousel__control q-carousel__navigation no-wrap absolute flex'
|
||||
+ ` q-carousel__navigation--${ type } q-carousel__navigation--${ navigationPosition.value }`
|
||||
+ (props.controlColor !== void 0 ? ` text-${ props.controlColor }` : '')
|
||||
}, [
|
||||
h('div', {
|
||||
class: 'q-carousel__navigation-inner flex flex-center no-wrap'
|
||||
}, getEnabledPanels().map(mapping))
|
||||
])
|
||||
}
|
||||
|
||||
function getContent () {
|
||||
const node = []
|
||||
|
||||
if (props.navigation === true) {
|
||||
const fn = slots[ 'navigation-icon' ] !== void 0
|
||||
? slots[ 'navigation-icon' ]
|
||||
: opts => h(QBtn, {
|
||||
key: 'nav' + opts.name,
|
||||
class: `q-carousel__navigation-icon q-carousel__navigation-icon--${ opts.active === true ? '' : 'in' }active`,
|
||||
...opts.btnProps,
|
||||
onClick: opts.onClick
|
||||
})
|
||||
|
||||
const maxIndex = panelsLen - 1
|
||||
node.push(
|
||||
getNavigationContainer('buttons', (panel, index) => {
|
||||
const name = panel.props.name
|
||||
const active = panelIndex.value === index
|
||||
|
||||
return fn({
|
||||
index,
|
||||
maxIndex,
|
||||
name,
|
||||
active,
|
||||
btnProps: {
|
||||
icon: active === true ? navActiveIcon.value : navIcon.value,
|
||||
size: 'sm',
|
||||
...controlProps.value
|
||||
},
|
||||
onClick: () => { goToPanel(name) }
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
else if (props.thumbnails === true) {
|
||||
const color = props.controlColor !== void 0
|
||||
? ` text-${ props.controlColor }`
|
||||
: ''
|
||||
|
||||
node.push(getNavigationContainer('thumbnails', panel => {
|
||||
const slide = panel.props
|
||||
|
||||
return h('img', {
|
||||
key: 'tmb#' + slide.name,
|
||||
class: `q-carousel__thumbnail q-carousel__thumbnail--${ slide.name === props.modelValue ? '' : 'in' }active` + color,
|
||||
src: slide.imgSrc || slide[ 'img-src' ],
|
||||
onClick: () => { goToPanel(slide.name) }
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
if (props.arrows === true && panelIndex.value >= 0) {
|
||||
if (props.infinite === true || panelIndex.value > 0) {
|
||||
node.push(
|
||||
h('div', {
|
||||
key: 'prev',
|
||||
class: `q-carousel__control q-carousel__arrow q-carousel__prev-arrow q-carousel__prev-arrow--${ direction.value } absolute flex flex-center`
|
||||
}, [
|
||||
h(QBtn, {
|
||||
icon: arrowIcons.value[ 0 ],
|
||||
...controlProps.value,
|
||||
onClick: previousPanel
|
||||
})
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
if (props.infinite === true || panelIndex.value < panelsLen - 1) {
|
||||
node.push(
|
||||
h('div', {
|
||||
key: 'next',
|
||||
class: 'q-carousel__control q-carousel__arrow q-carousel__next-arrow'
|
||||
+ ` q-carousel__next-arrow--${ direction.value } absolute flex flex-center`
|
||||
}, [
|
||||
h(QBtn, {
|
||||
icon: arrowIcons.value[ 1 ],
|
||||
...controlProps.value,
|
||||
onClick: nextPanel
|
||||
})
|
||||
])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return hMergeSlot(slots.control, node)
|
||||
}
|
||||
|
||||
return () => {
|
||||
panelsLen = updatePanelsList(slots)
|
||||
|
||||
return h('div', {
|
||||
class: classes.value,
|
||||
style: style.value
|
||||
}, [
|
||||
hDir(
|
||||
'div',
|
||||
{ class: 'q-carousel__slides-container' },
|
||||
getPanelContent(),
|
||||
'sl-cont',
|
||||
props.swipeable,
|
||||
() => panelDirectives.value
|
||||
)
|
||||
].concat(getContent()))
|
||||
}
|
||||
}
|
||||
})
|
||||
154
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarousel.json
generated
vendored
Normal file
154
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarousel.json
generated
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
{
|
||||
"mixins": [ "composables/private.use-panel/use-panel", "composables/private.use-fullscreen/use-fullscreen" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/carousel"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"dark": {
|
||||
"extends": "dark"
|
||||
},
|
||||
|
||||
"height": {
|
||||
"extends": "size",
|
||||
"desc": "Height of Carousel in CSS units, including unit name"
|
||||
},
|
||||
|
||||
"padding": {
|
||||
"type": "Boolean",
|
||||
"desc": "Applies a default padding to each slide, according to the usage of 'arrows' and 'navigation' props",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"control-color": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for QCarousel button controls (arrows, navigation) from the Quasar Color Palette"
|
||||
},
|
||||
|
||||
"control-text-color": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for text color of QCarousel button controls (arrows, navigation) from the Quasar Color Palette"
|
||||
},
|
||||
|
||||
"control-type": {
|
||||
"type": "String",
|
||||
"desc": "Type of button to use for controls (arrows, navigation)",
|
||||
"values": [ "'regular'", "'flat'", "'outline'", "'push'", "'unelevated'" ],
|
||||
"default": "'flat'",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"autoplay": {
|
||||
"type": [ "Number", "Boolean" ],
|
||||
"desc": "Jump to next slide (if 'true' or val > 0) or previous slide (if val < 0) at fixed time intervals (in milliseconds); 'false' disables autoplay, 'true' enables it for 5000ms intervals",
|
||||
"examples": [
|
||||
"true",
|
||||
"false",
|
||||
"2500"
|
||||
],
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"arrows": {
|
||||
"type": "Boolean",
|
||||
"desc": "Show navigation arrow buttons",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"prev-icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"next-icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"navigation": {
|
||||
"type": "Boolean",
|
||||
"desc": "Show navigation dots",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"navigation-position": {
|
||||
"type": "String",
|
||||
"desc": "Side to stick navigation to",
|
||||
"default": "# 'bottom'/'right'",
|
||||
"__runtimeDefault": true,
|
||||
"values": [ "'top'", "'right'", "'bottom'", "'left'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"navigation-icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"navigation-active-icon": {
|
||||
"extends": "icon",
|
||||
"desc": "Icon name following Quasar convention for the active (current slide) navigation icon; Make sure you have the icon library installed unless you are using 'img:' prefix"
|
||||
},
|
||||
|
||||
"thumbnails": {
|
||||
"type": "Boolean",
|
||||
"desc": "Show thumbnails",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"transition-prev": {
|
||||
"default": "'fade'",
|
||||
"__delete": [ "__runtimeDefault" ]
|
||||
},
|
||||
|
||||
"transition-next": {
|
||||
"default": "'fade'",
|
||||
"__delete": [ "__runtimeDefault" ]
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Suggestion: QCarouselSlide"
|
||||
},
|
||||
|
||||
"control": {
|
||||
"desc": "Slot specific for QCarouselControl"
|
||||
},
|
||||
|
||||
"navigation-icon": {
|
||||
"desc": "Slot for navigation icon/btn; Suggestion: QBtn",
|
||||
"scope": {
|
||||
"index": {
|
||||
"type": "Number",
|
||||
"desc": "The 0-based index of corresponding slide"
|
||||
},
|
||||
"maxIndex": {
|
||||
"type": "Number",
|
||||
"desc": "The available number of slides"
|
||||
},
|
||||
"name": {
|
||||
"type": "Any",
|
||||
"desc": "The name of the corresponding slide"
|
||||
},
|
||||
"active": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is this the current slide?"
|
||||
},
|
||||
"btnProps": {
|
||||
"type": "Object",
|
||||
"desc": "Default QBtn props that can be binded to your own QBtn"
|
||||
},
|
||||
"onClick": {
|
||||
"type": "Function",
|
||||
"desc": "Default trigger when clicked/tapped on",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
126
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarousel.sass
generated
vendored
Normal file
126
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarousel.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
.q-carousel
|
||||
background-color: #fff // needed for fullscreen
|
||||
height: 400px
|
||||
|
||||
&__slide
|
||||
min-height: 100%
|
||||
background-size: cover
|
||||
background-position: 50%
|
||||
|
||||
&__slide, .q-carousel--padding
|
||||
padding: 16px
|
||||
|
||||
&__slides-container
|
||||
height: 100%
|
||||
|
||||
&__control
|
||||
color: #fff
|
||||
|
||||
&__arrow
|
||||
pointer-events: none
|
||||
|
||||
.q-icon
|
||||
font-size: $carousel-arrow-icon-font-size
|
||||
.q-btn
|
||||
pointer-events: all
|
||||
|
||||
&__prev-arrow--horizontal,
|
||||
&__next-arrow--horizontal
|
||||
top: 16px
|
||||
bottom: 16px
|
||||
&__prev-arrow--horizontal
|
||||
left: 16px
|
||||
&__next-arrow--horizontal
|
||||
right: 16px
|
||||
|
||||
&__prev-arrow--vertical,
|
||||
&__next-arrow--vertical
|
||||
left: 16px
|
||||
right: 16px
|
||||
&__prev-arrow--vertical
|
||||
top: 16px
|
||||
&__next-arrow--vertical
|
||||
bottom: 16px
|
||||
|
||||
&__navigation
|
||||
|
||||
&--top,
|
||||
&--bottom
|
||||
left: 16px
|
||||
right: 16px
|
||||
overflow-x: auto
|
||||
overflow-y: hidden
|
||||
|
||||
&--top
|
||||
top: 16px
|
||||
|
||||
&--bottom
|
||||
bottom: 16px
|
||||
|
||||
&--left,
|
||||
&--right
|
||||
top: 16px
|
||||
bottom: 16px
|
||||
overflow-x: hidden
|
||||
overflow-y: auto
|
||||
|
||||
> .q-carousel__navigation-inner
|
||||
flex-direction: column
|
||||
|
||||
&--left
|
||||
left: 16px
|
||||
|
||||
&--right
|
||||
right: 16px
|
||||
|
||||
&-inner
|
||||
flex: 1 1 auto
|
||||
|
||||
.q-btn
|
||||
margin: 6px 4px
|
||||
padding: 5px
|
||||
|
||||
&__navigation-icon--inactive
|
||||
opacity: .7
|
||||
|
||||
.q-carousel__thumbnail
|
||||
margin: 2px
|
||||
height: 50px
|
||||
width: auto
|
||||
display: inline-block
|
||||
cursor: pointer
|
||||
border: 1px solid transparent
|
||||
border-radius: $generic-border-radius
|
||||
vertical-align: middle
|
||||
opacity: .7
|
||||
transition: opacity .3s
|
||||
|
||||
.q-carousel__thumbnail:hover,
|
||||
.q-carousel__thumbnail--active
|
||||
opacity: 1
|
||||
.q-carousel__thumbnail--active
|
||||
border-color: currentColor
|
||||
cursor: default
|
||||
|
||||
&--navigation-top,
|
||||
&--arrows-vertical
|
||||
&.q-carousel--with-padding .q-carousel__slide, .q-carousel--padding
|
||||
padding-top: 60px
|
||||
|
||||
&--navigation-bottom,
|
||||
&--arrows-vertical
|
||||
&.q-carousel--with-padding .q-carousel__slide, .q-carousel--padding
|
||||
padding-bottom: 60px
|
||||
|
||||
&--navigation-left,
|
||||
&--arrows-horizontal
|
||||
&.q-carousel--with-padding .q-carousel__slide, .q-carousel--padding
|
||||
padding-left: 60px
|
||||
|
||||
&--navigation-right,
|
||||
&--arrows-horizontal
|
||||
&.q-carousel--with-padding .q-carousel__slide, .q-carousel--padding
|
||||
padding-right: 60px
|
||||
|
||||
&.fullscreen
|
||||
height: 100%
|
||||
37
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarouselControl.js
generated
vendored
Normal file
37
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarouselControl.js
generated
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QCarouselControl',
|
||||
|
||||
props: {
|
||||
position: {
|
||||
type: String,
|
||||
default: 'bottom-right',
|
||||
validator: v => [
|
||||
'top-right', 'top-left',
|
||||
'bottom-right', 'bottom-left',
|
||||
'top', 'right', 'bottom', 'left'
|
||||
].includes(v)
|
||||
},
|
||||
offset: {
|
||||
type: Array,
|
||||
default: () => [ 18, 18 ],
|
||||
validator: v => v.length === 2
|
||||
}
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const classes = computed(() => `q-carousel__control absolute absolute-${ props.position }`)
|
||||
const style = computed(() => ({
|
||||
margin: `${ props.offset[ 1 ] }px ${ props.offset[ 0 ] }px`
|
||||
}))
|
||||
|
||||
return () => h('div', {
|
||||
class: classes.value,
|
||||
style: style.value
|
||||
}, hSlot(slots.default))
|
||||
}
|
||||
})
|
||||
33
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarouselControl.json
generated
vendored
Normal file
33
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarouselControl.json
generated
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/carousel"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"position": {
|
||||
"type": "String",
|
||||
"desc": "Side/corner to stick to",
|
||||
"default": "'bottom-right'",
|
||||
"values": [
|
||||
"'top-right'", "'top-left'",
|
||||
"'bottom-right'", "'bottom-left'",
|
||||
"'top'", "'right'", "'bottom'", "'left'"
|
||||
],
|
||||
"category": "position"
|
||||
},
|
||||
|
||||
"offset": {
|
||||
"type": "Array",
|
||||
"desc": "An array of two numbers to offset the component horizontally and vertically (in pixels)",
|
||||
"default": "[ 18, 18 ]",
|
||||
"examples": [ "[ 8, 8 ]", "[ 5, 10 ]" ],
|
||||
"category": "position"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"extends": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarouselSlide.js
generated
vendored
Normal file
28
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarouselSlide.js
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { usePanelChildProps } from '../../composables/private.use-panel/use-panel.js'
|
||||
|
||||
import { hSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QCarouselSlide',
|
||||
|
||||
props: {
|
||||
...usePanelChildProps,
|
||||
imgSrc: String
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const style = computed(() => (
|
||||
props.imgSrc
|
||||
? { backgroundImage: `url("${ props.imgSrc }")` }
|
||||
: {}
|
||||
))
|
||||
|
||||
return () => h('div', {
|
||||
class: 'q-carousel__slide',
|
||||
style: style.value
|
||||
}, hSlot(slots.default))
|
||||
}
|
||||
})
|
||||
33
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarouselSlide.json
generated
vendored
Normal file
33
Frontend-Learner/node_modules/quasar/src/components/carousel/QCarouselSlide.json
generated
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/carousel"
|
||||
},
|
||||
|
||||
"mixins": [ "composables/private.use-panel/use-panel.child" ],
|
||||
|
||||
"props": {
|
||||
"name": {
|
||||
"desc": "Slide name",
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"img-src": {
|
||||
"type": "String",
|
||||
"desc": "URL pointing to a slide background image (use public folder)",
|
||||
"transformAssetUrls": true,
|
||||
"examples": [
|
||||
"# (public folder) src=\"img/my-bg.png\"",
|
||||
"# (assets folder) src=\"~assets/my-img.png\"",
|
||||
"# (relative path format) :src=\"require('./my_img.jpg')\"",
|
||||
"# (URL) src=\"https://picsum.photos/500/300\""
|
||||
],
|
||||
"category": "model"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"extends": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
Frontend-Learner/node_modules/quasar/src/components/carousel/index.js
generated
vendored
Normal file
9
Frontend-Learner/node_modules/quasar/src/components/carousel/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import QCarousel from './QCarousel.js'
|
||||
import QCarouselSlide from './QCarouselSlide.js'
|
||||
import QCarouselControl from './QCarouselControl.js'
|
||||
|
||||
export {
|
||||
QCarousel,
|
||||
QCarouselSlide,
|
||||
QCarouselControl
|
||||
}
|
||||
156
Frontend-Learner/node_modules/quasar/src/components/chat/QChatMessage.js
generated
vendored
Normal file
156
Frontend-Learner/node_modules/quasar/src/components/chat/QChatMessage.js
generated
vendored
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { getNormalizedVNodes } from '../../utils/private.vm/vm.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'QChatMessage',
|
||||
|
||||
props: {
|
||||
sent: Boolean,
|
||||
label: String,
|
||||
bgColor: String,
|
||||
textColor: String,
|
||||
name: String,
|
||||
avatar: String,
|
||||
text: Array,
|
||||
stamp: String,
|
||||
size: String,
|
||||
labelHtml: Boolean,
|
||||
nameHtml: Boolean,
|
||||
textHtml: Boolean,
|
||||
stampHtml: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const op = computed(() => (props.sent === true ? 'sent' : 'received'))
|
||||
|
||||
const textClass = computed(() =>
|
||||
`q-message-text-content q-message-text-content--${ op.value }`
|
||||
+ (props.textColor !== void 0 ? ` text-${ props.textColor }` : '')
|
||||
)
|
||||
|
||||
const messageClass = computed(() =>
|
||||
`q-message-text q-message-text--${ op.value }`
|
||||
+ (props.bgColor !== void 0 ? ` text-${ props.bgColor }` : '')
|
||||
)
|
||||
|
||||
const containerClass = computed(() =>
|
||||
'q-message-container row items-end no-wrap'
|
||||
+ (props.sent === true ? ' reverse' : '')
|
||||
)
|
||||
|
||||
const sizeClass = computed(() => (props.size !== void 0 ? `col-${ props.size }` : ''))
|
||||
|
||||
const domProps = computed(() => ({
|
||||
msg: props.textHtml === true ? 'innerHTML' : 'textContent',
|
||||
stamp: props.stampHtml === true ? 'innerHTML' : 'textContent',
|
||||
name: props.nameHtml === true ? 'innerHTML' : 'textContent',
|
||||
label: props.labelHtml === true ? 'innerHTML' : 'textContent'
|
||||
}))
|
||||
|
||||
function wrapStamp (node) {
|
||||
if (slots.stamp !== void 0) {
|
||||
return [ node, h('div', { class: 'q-message-stamp' }, slots.stamp()) ]
|
||||
}
|
||||
|
||||
if (props.stamp) {
|
||||
return [
|
||||
node,
|
||||
h('div', {
|
||||
class: 'q-message-stamp',
|
||||
[ domProps.value.stamp ]: props.stamp
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
return [ node ]
|
||||
}
|
||||
|
||||
function getText (contentList, withSlots) {
|
||||
const content = withSlots === true
|
||||
? (contentList.length > 1 ? text => text : text => h('div', [ text ]))
|
||||
: text => h('div', { [ domProps.value.msg ]: text })
|
||||
|
||||
return contentList.map((msg, index) => h('div', {
|
||||
key: index,
|
||||
class: messageClass.value
|
||||
}, [
|
||||
h('div', { class: textClass.value }, wrapStamp(content(msg)))
|
||||
]))
|
||||
}
|
||||
|
||||
return () => {
|
||||
const container = []
|
||||
|
||||
if (slots.avatar !== void 0) {
|
||||
container.push(slots.avatar())
|
||||
}
|
||||
else if (props.avatar !== void 0) {
|
||||
container.push(
|
||||
h('img', {
|
||||
class: `q-message-avatar q-message-avatar--${ op.value }`,
|
||||
src: props.avatar,
|
||||
'aria-hidden': 'true'
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const msg = []
|
||||
|
||||
if (slots.name !== void 0) {
|
||||
msg.push(
|
||||
h('div', { class: `q-message-name q-message-name--${ op.value }` }, slots.name())
|
||||
)
|
||||
}
|
||||
else if (props.name !== void 0) {
|
||||
msg.push(
|
||||
h('div', {
|
||||
class: `q-message-name q-message-name--${ op.value }`,
|
||||
[ domProps.value.name ]: props.name
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (slots.default !== void 0) {
|
||||
msg.push(
|
||||
getText(
|
||||
getNormalizedVNodes(slots.default()),
|
||||
true
|
||||
)
|
||||
)
|
||||
}
|
||||
else if (props.text !== void 0) {
|
||||
msg.push(getText(props.text))
|
||||
}
|
||||
|
||||
container.push(
|
||||
h('div', { class: sizeClass.value }, msg)
|
||||
)
|
||||
|
||||
const child = []
|
||||
|
||||
if (slots.label !== void 0) {
|
||||
child.push(
|
||||
h('div', { class: 'q-message-label' }, slots.label())
|
||||
)
|
||||
}
|
||||
else if (props.label !== void 0) {
|
||||
child.push(
|
||||
h('div', {
|
||||
class: 'q-message-label',
|
||||
[ domProps.value.label ]: props.label
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
child.push(
|
||||
h('div', { class: containerClass.value }, container)
|
||||
)
|
||||
|
||||
return h('div', {
|
||||
class: `q-message q-message-${ op.value }`
|
||||
}, child)
|
||||
}
|
||||
}
|
||||
})
|
||||
115
Frontend-Learner/node_modules/quasar/src/components/chat/QChatMessage.json
generated
vendored
Normal file
115
Frontend-Learner/node_modules/quasar/src/components/chat/QChatMessage.json
generated
vendored
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/chat"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"sent": {
|
||||
"type": "Boolean",
|
||||
"desc": "Render as a sent message (so from current user)",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"label": {
|
||||
"type": "String",
|
||||
"desc": "Renders a label header/section only",
|
||||
"examples": [ "'Friday, 18th'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"bg-color": {
|
||||
"extends": "color",
|
||||
"desc": "Color name (from the Quasar Color Palette) for chat bubble background",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"text-color": {
|
||||
"extends": "text-color",
|
||||
"desc": "Color name (from the Quasar Color Palette) for chat bubble text",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"name": {
|
||||
"type": "String",
|
||||
"desc": "Author's name",
|
||||
"examples": [ "'John Doe'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"avatar": {
|
||||
"type": "String",
|
||||
"desc": "URL to the avatar image of the author",
|
||||
"transformAssetUrls": true,
|
||||
"examples": [
|
||||
"# (public folder) src=\"boy-avatar.png\"",
|
||||
"# (assets folder) src=\"~assets/boy-avatar.png\"",
|
||||
"# (relative path format) :src=\"require('./my_img.jpg')\"",
|
||||
"# (URL) src=\"https://picsum.photos/500/300\""
|
||||
],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"text": {
|
||||
"type": "Array",
|
||||
"desc": "Array of strings that are the message body. Strings are not sanitized (see details in docs)",
|
||||
"examples": [ "[ 'How are you?' ]", "[ 'I\\'m good, thank you!', 'And you?' ]" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"stamp": {
|
||||
"type": "String",
|
||||
"desc": "Creation timestamp",
|
||||
"examples": [ "'13:55'", "'Yesterday at 13:51'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"size": {
|
||||
"type": "String",
|
||||
"desc": "1-12 out of 12 (same as col-*)",
|
||||
"examples": [ "'4'", "'6'", "'12'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"label-html": {
|
||||
"extends": "html",
|
||||
"desc": "Render the label as HTML; This can lead to XSS attacks so make sure that you sanitize the message first"
|
||||
},
|
||||
|
||||
"name-html": {
|
||||
"extends": "html",
|
||||
"desc": "Render the name as HTML; This can lead to XSS attacks so make sure that you sanitize the message first"
|
||||
},
|
||||
|
||||
"text-html": {
|
||||
"extends": "html",
|
||||
"desc": "Render the text as HTML; This can lead to XSS attacks so make sure that you sanitize the message first"
|
||||
},
|
||||
|
||||
"stamp-html": {
|
||||
"extends": "html",
|
||||
"desc": "Render the stamp as HTML; This can lead to XSS attacks so make sure that you sanitize the message first"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "You can use this slot to define a custom message (overrides props)"
|
||||
},
|
||||
|
||||
"avatar": {
|
||||
"desc": "Slot for avatar; Suggestion: QAvatar, img"
|
||||
},
|
||||
|
||||
"name": {
|
||||
"desc": "Slot for name; Overrides the 'name' prop"
|
||||
},
|
||||
|
||||
"stamp": {
|
||||
"desc": "Slot for stamp; Overrides the 'stamp' prop"
|
||||
},
|
||||
|
||||
"label": {
|
||||
"desc": "Slot for label; Overrides the 'label' prop"
|
||||
}
|
||||
}
|
||||
}
|
||||
77
Frontend-Learner/node_modules/quasar/src/components/chat/QChatMessage.sass
generated
vendored
Normal file
77
Frontend-Learner/node_modules/quasar/src/components/chat/QChatMessage.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
.q-message-name
|
||||
font-size: $chat-message-name-font-size
|
||||
|
||||
.q-message-label
|
||||
margin: (3 * $chat-message-distance) 0
|
||||
text-align: center
|
||||
font-size: $chat-message-label-font-size
|
||||
|
||||
.q-message-stamp
|
||||
color: inherit
|
||||
margin-top: 4px
|
||||
opacity: .6
|
||||
display: none
|
||||
font-size: $chat-message-stamp-font-size
|
||||
|
||||
.q-message-avatar
|
||||
border-radius: 50%
|
||||
width: $chat-message-avatar-size
|
||||
height: $chat-message-avatar-size
|
||||
min-width: $chat-message-avatar-size
|
||||
|
||||
.q-message
|
||||
margin-bottom: $chat-message-distance
|
||||
&:first-child .q-message-label
|
||||
margin-top: 0
|
||||
|
||||
.q-message-avatar--received
|
||||
margin-right: 8px
|
||||
.q-message-text--received
|
||||
color: $chat-message-received-bg
|
||||
border-radius: $chat-message-border-radius $chat-message-border-radius $chat-message-border-radius 0
|
||||
&:last-child:before
|
||||
right: 100%
|
||||
border-right: 0 solid transparent
|
||||
border-left: 8px solid transparent
|
||||
border-bottom: 8px solid currentColor
|
||||
.q-message-text-content--received
|
||||
color: $chat-message-received-color
|
||||
|
||||
.q-message-name--sent
|
||||
text-align: right
|
||||
.q-message-avatar--sent
|
||||
margin-left: 8px
|
||||
.q-message-container--sent
|
||||
flex-direction: row-reverse
|
||||
.q-message-text--sent
|
||||
color: $chat-message-sent-bg
|
||||
border-radius: $chat-message-border-radius $chat-message-border-radius 0 $chat-message-border-radius
|
||||
&:last-child:before
|
||||
left: 100%
|
||||
border-left: 0 solid transparent
|
||||
border-right: 8px solid transparent
|
||||
border-bottom: 8px solid currentColor
|
||||
.q-message-text-content--sent
|
||||
color: $chat-message-sent-color
|
||||
|
||||
.q-message-text
|
||||
background: currentColor
|
||||
padding: $chat-message-text-padding
|
||||
line-height: max(1.2, $min-line-height)
|
||||
word-break: break-word
|
||||
position: relative
|
||||
|
||||
& + &
|
||||
margin-top: 3px
|
||||
|
||||
&:last-child
|
||||
min-height: $chat-message-avatar-size
|
||||
|
||||
.q-message-stamp
|
||||
display: block
|
||||
&:before
|
||||
content: ''
|
||||
position: absolute
|
||||
bottom: 0
|
||||
width: 0
|
||||
height: 0
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/chat/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/chat/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QChatMessage from './QChatMessage.js'
|
||||
|
||||
export {
|
||||
QChatMessage
|
||||
}
|
||||
68
Frontend-Learner/node_modules/quasar/src/components/checkbox/QCheckbox.js
generated
vendored
Normal file
68
Frontend-Learner/node_modules/quasar/src/components/checkbox/QCheckbox.js
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import { h, computed } from 'vue'
|
||||
|
||||
import QIcon from '../icon/QIcon.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import useCheckbox, { useCheckboxProps, useCheckboxEmits } from './use-checkbox.js'
|
||||
|
||||
const createBgNode = () => h('div', {
|
||||
key: 'svg',
|
||||
class: 'q-checkbox__bg absolute'
|
||||
}, [
|
||||
h('svg', {
|
||||
class: 'q-checkbox__svg fit absolute-full',
|
||||
viewBox: '0 0 24 24'
|
||||
}, [
|
||||
h('path', {
|
||||
class: 'q-checkbox__truthy',
|
||||
fill: 'none',
|
||||
d: 'M1.73,12.91 8.1,19.28 22.79,4.59'
|
||||
}),
|
||||
|
||||
h('path', {
|
||||
class: 'q-checkbox__indet',
|
||||
d: 'M4,14H20V10H4'
|
||||
})
|
||||
])
|
||||
])
|
||||
|
||||
export default createComponent({
|
||||
name: 'QCheckbox',
|
||||
|
||||
props: useCheckboxProps,
|
||||
emits: useCheckboxEmits,
|
||||
|
||||
setup (props) {
|
||||
const bgNode = createBgNode()
|
||||
|
||||
function getInner (isTrue, isIndeterminate) {
|
||||
const icon = computed(() =>
|
||||
(isTrue.value === true
|
||||
? props.checkedIcon
|
||||
: (isIndeterminate.value === true
|
||||
? props.indeterminateIcon
|
||||
: props.uncheckedIcon
|
||||
)
|
||||
) || null
|
||||
)
|
||||
|
||||
return () => (
|
||||
icon.value !== null
|
||||
? [
|
||||
h('div', {
|
||||
key: 'icon',
|
||||
class: 'q-checkbox__icon-container absolute-full flex flex-center no-wrap'
|
||||
}, [
|
||||
h(QIcon, {
|
||||
class: 'q-checkbox__icon',
|
||||
name: icon.value
|
||||
})
|
||||
])
|
||||
]
|
||||
: [ bgNode ]
|
||||
)
|
||||
}
|
||||
|
||||
return useCheckbox('checkbox', getInner)
|
||||
}
|
||||
})
|
||||
24
Frontend-Learner/node_modules/quasar/src/components/checkbox/QCheckbox.json
generated
vendored
Normal file
24
Frontend-Learner/node_modules/quasar/src/components/checkbox/QCheckbox.json
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"mixins": [ "components/checkbox/use-checkbox" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/checkbox"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"checked-icon": {
|
||||
"desc": "The icon to be used when the model is truthy (instead of the default design)",
|
||||
"addedIn": "v2.5"
|
||||
},
|
||||
|
||||
"unchecked-icon": {
|
||||
"desc": "The icon to be used when the toggle is falsy (instead of the default design)",
|
||||
"addedIn": "v2.5"
|
||||
},
|
||||
|
||||
"indeterminate-icon": {
|
||||
"desc": "The icon to be used when the model is indeterminate (instead of the default design)",
|
||||
"addedIn": "v2.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Frontend-Learner/node_modules/quasar/src/components/checkbox/QCheckbox.sass
generated
vendored
Normal file
122
Frontend-Learner/node_modules/quasar/src/components/checkbox/QCheckbox.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
$checkbox-transition: .22s cubic-bezier(0,0,.2,1) 0ms
|
||||
|
||||
.q-checkbox
|
||||
vertical-align: middle
|
||||
|
||||
&__native
|
||||
width: 1px
|
||||
height: 1px
|
||||
|
||||
&__bg,
|
||||
&__icon-container
|
||||
user-select: none
|
||||
|
||||
&__bg
|
||||
top: 25%
|
||||
left: 25%
|
||||
width: 50%
|
||||
height: 50%
|
||||
border: 2px solid currentColor
|
||||
border-radius: 2px
|
||||
transition: background $checkbox-transition
|
||||
-webkit-print-color-adjust: exact
|
||||
|
||||
&__icon
|
||||
color: currentColor
|
||||
font-size: .5em
|
||||
|
||||
&__svg
|
||||
color: #fff
|
||||
|
||||
&__truthy
|
||||
stroke: currentColor
|
||||
stroke-width: 3.12px
|
||||
stroke-dashoffset: 29.78334
|
||||
stroke-dasharray: 29.78334
|
||||
|
||||
&__indet
|
||||
fill: currentColor
|
||||
transform-origin: 50% 50%
|
||||
transform: rotate(-280deg) scale(0)
|
||||
|
||||
&__inner
|
||||
font-size: $checkbox-inner-font-size
|
||||
width: 1em
|
||||
min-width: 1em
|
||||
height: 1em
|
||||
outline: 0
|
||||
border-radius: 50%
|
||||
color: rgba(0,0,0,.54)
|
||||
|
||||
&--truthy, &--indet
|
||||
color: var(--q-primary)
|
||||
.q-checkbox__bg
|
||||
background: currentColor
|
||||
|
||||
&--truthy
|
||||
path
|
||||
stroke-dashoffset: 0
|
||||
transition: stroke-dashoffset .18s cubic-bezier(.4,0,.6,1) 0ms
|
||||
|
||||
&--indet
|
||||
.q-checkbox__indet
|
||||
transform: rotate(0) scale(1)
|
||||
transition: transform $checkbox-transition
|
||||
|
||||
&.disabled
|
||||
opacity: .75 !important
|
||||
|
||||
&--dark
|
||||
.q-checkbox__inner
|
||||
color: rgba(255,255,255,.7)
|
||||
&:before
|
||||
opacity: .32 !important
|
||||
&--truthy, &--indet
|
||||
color: var(--q-primary)
|
||||
|
||||
&--dense
|
||||
|
||||
.q-checkbox__inner
|
||||
width: .5em
|
||||
min-width: .5em
|
||||
height: .5em
|
||||
|
||||
.q-checkbox__bg
|
||||
left: 5%
|
||||
top: 5%
|
||||
width: 90%
|
||||
height: 90%
|
||||
|
||||
.q-checkbox__label
|
||||
padding-left: .5em
|
||||
|
||||
&.reverse .q-checkbox__label
|
||||
padding-left: 0
|
||||
padding-right: .5em
|
||||
|
||||
body.desktop
|
||||
|
||||
.q-checkbox:not(.disabled)
|
||||
.q-checkbox__inner:before
|
||||
content: ''
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
border-radius: 50%
|
||||
background: currentColor
|
||||
opacity: .12
|
||||
transform: scale3d(0, 0, 1)
|
||||
transition: transform $option-focus-transition
|
||||
|
||||
&:focus,
|
||||
&:hover
|
||||
.q-checkbox__inner:before
|
||||
transform: scale3d(1, 1, 1)
|
||||
|
||||
.q-checkbox--dense:not(.disabled)
|
||||
&:focus,
|
||||
&:hover
|
||||
.q-checkbox__inner:before
|
||||
transform: scale3d(1.4, 1.4, 1)
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/checkbox/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/checkbox/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QCheckbox from './QCheckbox.js'
|
||||
|
||||
export {
|
||||
QCheckbox
|
||||
}
|
||||
244
Frontend-Learner/node_modules/quasar/src/components/checkbox/use-checkbox.js
generated
vendored
Normal file
244
Frontend-Learner/node_modules/quasar/src/components/checkbox/use-checkbox.js
generated
vendored
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
import { h, ref, computed, getCurrentInstance, toRaw } from 'vue'
|
||||
|
||||
import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js'
|
||||
import useSize, { useSizeProps } from '../../composables/private.use-size/use-size.js'
|
||||
import useRefocusTarget from '../../composables/private.use-refocus-target/use-refocus-target.js'
|
||||
import { useFormInject, useFormProps } from '../../composables/use-form/private.use-form.js'
|
||||
|
||||
import optionSizes from '../../utils/private.option-sizes/option-sizes.js'
|
||||
import { stopAndPrevent } from '../../utils/event/event.js'
|
||||
import { hSlot, hMergeSlot } from '../../utils/private.render/render.js'
|
||||
|
||||
export const useCheckboxProps = {
|
||||
...useDarkProps,
|
||||
...useSizeProps,
|
||||
...useFormProps,
|
||||
|
||||
modelValue: {
|
||||
required: true,
|
||||
default: null
|
||||
},
|
||||
val: {},
|
||||
|
||||
trueValue: { default: true },
|
||||
falseValue: { default: false },
|
||||
indeterminateValue: { default: null },
|
||||
|
||||
checkedIcon: String,
|
||||
uncheckedIcon: String,
|
||||
indeterminateIcon: String,
|
||||
|
||||
toggleOrder: {
|
||||
type: String,
|
||||
validator: v => v === 'tf' || v === 'ft'
|
||||
},
|
||||
toggleIndeterminate: Boolean,
|
||||
|
||||
label: String,
|
||||
leftLabel: Boolean,
|
||||
|
||||
color: String,
|
||||
keepColor: Boolean,
|
||||
dense: Boolean,
|
||||
|
||||
disable: Boolean,
|
||||
tabindex: [ String, Number ]
|
||||
}
|
||||
|
||||
export const useCheckboxEmits = [ 'update:modelValue' ]
|
||||
|
||||
export default function (type, getInner) {
|
||||
const { props, slots, emit, proxy } = getCurrentInstance()
|
||||
const { $q } = proxy
|
||||
|
||||
const isDark = useDark(props, $q)
|
||||
|
||||
const rootRef = ref(null)
|
||||
const { refocusTargetEl, refocusTarget } = useRefocusTarget(props, rootRef)
|
||||
const sizeStyle = useSize(props, optionSizes)
|
||||
|
||||
const modelIsArray = computed(() =>
|
||||
props.val !== void 0 && Array.isArray(props.modelValue)
|
||||
)
|
||||
|
||||
const index = computed(() => {
|
||||
const val = toRaw(props.val)
|
||||
return modelIsArray.value === true
|
||||
? props.modelValue.findIndex(opt => toRaw(opt) === val)
|
||||
: -1
|
||||
})
|
||||
|
||||
const isTrue = computed(() => (
|
||||
modelIsArray.value === true
|
||||
? index.value !== -1
|
||||
: toRaw(props.modelValue) === toRaw(props.trueValue)
|
||||
))
|
||||
|
||||
const isFalse = computed(() => (
|
||||
modelIsArray.value === true
|
||||
? index.value === -1
|
||||
: toRaw(props.modelValue) === toRaw(props.falseValue)
|
||||
))
|
||||
|
||||
const isIndeterminate = computed(() =>
|
||||
isTrue.value === false && isFalse.value === false
|
||||
)
|
||||
|
||||
const tabindex = computed(() => (
|
||||
props.disable === true ? -1 : props.tabindex || 0
|
||||
))
|
||||
|
||||
const classes = computed(() =>
|
||||
`q-${ type } cursor-pointer no-outline row inline no-wrap items-center`
|
||||
+ (props.disable === true ? ' disabled' : '')
|
||||
+ (isDark.value === true ? ` q-${ type }--dark` : '')
|
||||
+ (props.dense === true ? ` q-${ type }--dense` : '')
|
||||
+ (props.leftLabel === true ? ' reverse' : '')
|
||||
)
|
||||
|
||||
const innerClass = computed(() => {
|
||||
const state = isTrue.value === true ? 'truthy' : (isFalse.value === true ? 'falsy' : 'indet')
|
||||
const color = props.color !== void 0 && (
|
||||
props.keepColor === true
|
||||
|| (type === 'toggle' ? isTrue.value === true : isFalse.value !== true)
|
||||
)
|
||||
? ` text-${ props.color }`
|
||||
: ''
|
||||
|
||||
return `q-${ type }__inner relative-position non-selectable q-${ type }__inner--${ state }${ color }`
|
||||
})
|
||||
|
||||
const formAttrs = computed(() => {
|
||||
const prop = { type: 'checkbox' }
|
||||
|
||||
props.name !== void 0 && Object.assign(prop, {
|
||||
// see https://vuejs.org/guide/extras/render-function.html#creating-vnodes (.prop)
|
||||
'.checked': isTrue.value,
|
||||
'^checked': isTrue.value === true ? 'checked' : void 0,
|
||||
name: props.name,
|
||||
value: modelIsArray.value === true
|
||||
? props.val
|
||||
: props.trueValue
|
||||
})
|
||||
|
||||
return prop
|
||||
})
|
||||
|
||||
const injectFormInput = useFormInject(formAttrs)
|
||||
|
||||
const attributes = computed(() => {
|
||||
const attrs = {
|
||||
tabindex: tabindex.value,
|
||||
role: type === 'toggle' ? 'switch' : 'checkbox',
|
||||
'aria-label': props.label,
|
||||
'aria-checked': isIndeterminate.value === true
|
||||
? 'mixed'
|
||||
: (isTrue.value === true ? 'true' : 'false')
|
||||
}
|
||||
|
||||
if (props.disable === true) {
|
||||
attrs[ 'aria-disabled' ] = 'true'
|
||||
}
|
||||
|
||||
return attrs
|
||||
})
|
||||
|
||||
function onClick (e) {
|
||||
if (e !== void 0) {
|
||||
stopAndPrevent(e)
|
||||
refocusTarget(e)
|
||||
}
|
||||
|
||||
if (props.disable !== true) {
|
||||
emit('update:modelValue', getNextValue(), e)
|
||||
}
|
||||
}
|
||||
|
||||
function getNextValue () {
|
||||
if (modelIsArray.value === true) {
|
||||
if (isTrue.value === true) {
|
||||
const val = props.modelValue.slice()
|
||||
val.splice(index.value, 1)
|
||||
return val
|
||||
}
|
||||
|
||||
return props.modelValue.concat([ props.val ])
|
||||
}
|
||||
|
||||
if (isTrue.value === true) {
|
||||
if (props.toggleOrder !== 'ft' || props.toggleIndeterminate === false) {
|
||||
return props.falseValue
|
||||
}
|
||||
}
|
||||
else if (isFalse.value === true) {
|
||||
if (props.toggleOrder === 'ft' || props.toggleIndeterminate === false) {
|
||||
return props.trueValue
|
||||
}
|
||||
}
|
||||
else {
|
||||
return props.toggleOrder !== 'ft'
|
||||
? props.trueValue
|
||||
: props.falseValue
|
||||
}
|
||||
|
||||
return props.indeterminateValue
|
||||
}
|
||||
|
||||
function onKeydown (e) {
|
||||
if (e.keyCode === 13 || e.keyCode === 32) {
|
||||
stopAndPrevent(e)
|
||||
}
|
||||
}
|
||||
|
||||
function onKeyup (e) {
|
||||
if (e.keyCode === 13 || e.keyCode === 32) {
|
||||
onClick(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getInnerContent = getInner(isTrue, isIndeterminate)
|
||||
|
||||
// expose public methods
|
||||
Object.assign(proxy, { toggle: onClick })
|
||||
|
||||
return () => {
|
||||
const inner = getInnerContent()
|
||||
|
||||
props.disable !== true && injectFormInput(
|
||||
inner,
|
||||
'unshift',
|
||||
` q-${ type }__native absolute q-ma-none q-pa-none`
|
||||
)
|
||||
|
||||
const child = [
|
||||
h('div', {
|
||||
class: innerClass.value,
|
||||
style: sizeStyle.value,
|
||||
'aria-hidden': 'true'
|
||||
}, inner)
|
||||
]
|
||||
|
||||
if (refocusTargetEl.value !== null) {
|
||||
child.push(refocusTargetEl.value)
|
||||
}
|
||||
|
||||
const label = props.label !== void 0
|
||||
? hMergeSlot(slots.default, [ props.label ])
|
||||
: hSlot(slots.default)
|
||||
|
||||
label !== void 0 && child.push(
|
||||
h('div', {
|
||||
class: `q-${ type }__label q-anchor--skip`
|
||||
}, label)
|
||||
)
|
||||
|
||||
return h('div', {
|
||||
ref: rootRef,
|
||||
class: classes.value,
|
||||
...attributes.value,
|
||||
onClick,
|
||||
onKeydown,
|
||||
onKeyup
|
||||
}, child)
|
||||
}
|
||||
}
|
||||
144
Frontend-Learner/node_modules/quasar/src/components/checkbox/use-checkbox.json
generated
vendored
Normal file
144
Frontend-Learner/node_modules/quasar/src/components/checkbox/use-checkbox.json
generated
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
{
|
||||
"mixins": [ "composables/private.use-size/use-size", "composables/use-form/private.use-form" ],
|
||||
|
||||
"props": {
|
||||
"model-value": {
|
||||
"extends": "model-value",
|
||||
"type": [ "Any", "Array" ],
|
||||
"default": "null",
|
||||
"examples": [ "false", "[ 'car', 'building' ]" ]
|
||||
},
|
||||
|
||||
"val": {
|
||||
"type": "Any",
|
||||
"desc": "Works when model ('value') is Array. It tells the component which value should add/remove when ticked/unticked",
|
||||
"examples": [ "'car'" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"true-value": {
|
||||
"type": "Any",
|
||||
"desc": "What model value should be considered as checked/ticked/on?",
|
||||
"default": "true",
|
||||
"examples": [ "'Agreed'" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"false-value": {
|
||||
"type": "Any",
|
||||
"desc": "What model value should be considered as unchecked/unticked/off?",
|
||||
"default": "false",
|
||||
"examples": [ "'Disagree'" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"indeterminate-value": {
|
||||
"type": "Any",
|
||||
"desc": "What model value should be considered as 'indeterminate'?",
|
||||
"default": "null",
|
||||
"examples": [ "0", "'not_answered'" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"toggle-order": {
|
||||
"type": "String",
|
||||
"desc": "Determines toggle order of the two states ('t' stands for state of true, 'f' for state of false); If 'toggle-indeterminate' is true, then the order is: indet -> first state -> second state -> indet (and repeat), otherwise: indet -> first state -> second state -> first state -> second state -> ...",
|
||||
"values": [ "'tf'", "'ft'" ],
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"toggle-indeterminate": {
|
||||
"type": "Boolean",
|
||||
"desc": "When user clicks/taps on the component, should we toggle through the indeterminate state too?",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"label": {
|
||||
"type": "String",
|
||||
"desc": "Label to display along the component (or use the default slot instead of this prop)",
|
||||
"examples": [ "'I agree with the Terms and Conditions'" ],
|
||||
"category": "label"
|
||||
},
|
||||
|
||||
"left-label": {
|
||||
"type": "Boolean",
|
||||
"desc": "Label (if any specified) should be displayed on the left side of the component",
|
||||
"category": "label"
|
||||
},
|
||||
|
||||
"checked-icon": {
|
||||
"type": "String",
|
||||
"examples": [ "'visibility'" ],
|
||||
"category": "icons"
|
||||
},
|
||||
|
||||
"unchecked-icon": {
|
||||
"type": "String",
|
||||
"examples": [ "'visibility_off'" ],
|
||||
"category": "icons"
|
||||
},
|
||||
|
||||
"indeterminate-icon": {
|
||||
"type": "String",
|
||||
"examples": [ "'help'" ],
|
||||
"category": "icons"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"keep-color": {
|
||||
"type": "Boolean",
|
||||
"desc": "Should the color (if specified any) be kept when the component is unticked/ off?",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"dark": {
|
||||
"extends": "dark"
|
||||
},
|
||||
|
||||
"dense": {
|
||||
"extends": "dense"
|
||||
},
|
||||
|
||||
"disable": {
|
||||
"extends": "disable"
|
||||
},
|
||||
|
||||
"tabindex": {
|
||||
"extends": "tabindex"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"update:model-value": {
|
||||
"desc": "Emitted when the component needs to change the model; Is also used by v-model",
|
||||
"params": {
|
||||
"value": {
|
||||
"type": "Any",
|
||||
"desc": "New model value",
|
||||
"required": true
|
||||
},
|
||||
"evt": {
|
||||
"extends": "evt",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"toggle": {
|
||||
"desc": "Toggle the state (of the model)",
|
||||
"params": null,
|
||||
"returns": null
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Default slot can be used as label, unless 'label' prop is specified; Suggestion: string"
|
||||
}
|
||||
}
|
||||
}
|
||||
209
Frontend-Learner/node_modules/quasar/src/components/chip/QChip.js
generated
vendored
Normal file
209
Frontend-Learner/node_modules/quasar/src/components/chip/QChip.js
generated
vendored
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
import { h, computed, getCurrentInstance } from 'vue'
|
||||
|
||||
import QIcon from '../icon/QIcon.js'
|
||||
|
||||
import Ripple from '../../directives/ripple/Ripple.js'
|
||||
|
||||
import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js'
|
||||
import useSize, { useSizeProps } from '../../composables/private.use-size/use-size.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { stopAndPrevent } from '../../utils/event/event.js'
|
||||
import { hMergeSlotSafely, hDir } from '../../utils/private.render/render.js'
|
||||
|
||||
export const defaultSizes = {
|
||||
xs: 8,
|
||||
sm: 10,
|
||||
md: 14,
|
||||
lg: 20,
|
||||
xl: 24
|
||||
}
|
||||
|
||||
export default createComponent({
|
||||
name: 'QChip',
|
||||
|
||||
props: {
|
||||
...useDarkProps,
|
||||
...useSizeProps,
|
||||
|
||||
dense: Boolean,
|
||||
|
||||
icon: String,
|
||||
iconRight: String,
|
||||
iconRemove: String,
|
||||
iconSelected: String,
|
||||
label: [ String, Number ],
|
||||
|
||||
color: String,
|
||||
textColor: String,
|
||||
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
selected: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
|
||||
square: Boolean,
|
||||
outline: Boolean,
|
||||
clickable: Boolean,
|
||||
removable: Boolean,
|
||||
|
||||
removeAriaLabel: String,
|
||||
|
||||
tabindex: [ String, Number ],
|
||||
disable: Boolean,
|
||||
|
||||
ripple: {
|
||||
type: [ Boolean, Object ],
|
||||
default: true
|
||||
}
|
||||
},
|
||||
|
||||
emits: [ 'update:modelValue', 'update:selected', 'remove', 'click' ],
|
||||
|
||||
setup (props, { slots, emit }) {
|
||||
const { proxy: { $q } } = getCurrentInstance()
|
||||
|
||||
const isDark = useDark(props, $q)
|
||||
const sizeStyle = useSize(props, defaultSizes)
|
||||
|
||||
const hasLeftIcon = computed(() => props.selected === true || props.icon !== void 0)
|
||||
|
||||
const leftIcon = computed(() => (
|
||||
props.selected === true
|
||||
? props.iconSelected || $q.iconSet.chip.selected
|
||||
: props.icon
|
||||
))
|
||||
|
||||
const removeIcon = computed(() => props.iconRemove || $q.iconSet.chip.remove)
|
||||
|
||||
const isClickable = computed(() =>
|
||||
props.disable === false
|
||||
&& (props.clickable === true || props.selected !== null)
|
||||
)
|
||||
|
||||
const classes = computed(() => {
|
||||
const text = props.outline === true
|
||||
? props.color || props.textColor
|
||||
: props.textColor
|
||||
|
||||
return 'q-chip row inline no-wrap items-center'
|
||||
+ (props.outline === false && props.color !== void 0 ? ` bg-${ props.color }` : '')
|
||||
+ (text ? ` text-${ text } q-chip--colored` : '')
|
||||
+ (props.disable === true ? ' disabled' : '')
|
||||
+ (props.dense === true ? ' q-chip--dense' : '')
|
||||
+ (props.outline === true ? ' q-chip--outline' : '')
|
||||
+ (props.selected === true ? ' q-chip--selected' : '')
|
||||
+ (isClickable.value === true ? ' q-chip--clickable cursor-pointer non-selectable q-hoverable' : '')
|
||||
+ (props.square === true ? ' q-chip--square' : '')
|
||||
+ (isDark.value === true ? ' q-chip--dark q-dark' : '')
|
||||
})
|
||||
|
||||
const attributes = computed(() => {
|
||||
const chip = props.disable === true
|
||||
? { tabindex: -1, 'aria-disabled': 'true' }
|
||||
: { tabindex: props.tabindex || 0 }
|
||||
|
||||
const remove = {
|
||||
...chip,
|
||||
role: 'button',
|
||||
'aria-hidden': 'false',
|
||||
'aria-label': props.removeAriaLabel || $q.lang.label.remove
|
||||
}
|
||||
|
||||
return { chip, remove }
|
||||
})
|
||||
|
||||
function onKeyup (e) {
|
||||
e.keyCode === 13 /* ENTER */ && onClick(e)
|
||||
}
|
||||
|
||||
function onClick (e) {
|
||||
if (!props.disable) {
|
||||
emit('update:selected', !props.selected)
|
||||
emit('click', e)
|
||||
}
|
||||
}
|
||||
|
||||
function onRemove (e) {
|
||||
if (e.keyCode === void 0 || e.keyCode === 13) {
|
||||
stopAndPrevent(e)
|
||||
if (props.disable === false) {
|
||||
emit('update:modelValue', false)
|
||||
emit('remove')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getContent () {
|
||||
const child = []
|
||||
|
||||
isClickable.value === true && child.push(
|
||||
h('div', { class: 'q-focus-helper' })
|
||||
)
|
||||
|
||||
hasLeftIcon.value === true && child.push(
|
||||
h(QIcon, {
|
||||
class: 'q-chip__icon q-chip__icon--left',
|
||||
name: leftIcon.value
|
||||
})
|
||||
)
|
||||
|
||||
const label = props.label !== void 0
|
||||
? [ h('div', { class: 'ellipsis' }, [ props.label ]) ]
|
||||
: void 0
|
||||
|
||||
child.push(
|
||||
h('div', {
|
||||
class: 'q-chip__content col row no-wrap items-center q-anchor--skip'
|
||||
}, hMergeSlotSafely(slots.default, label))
|
||||
)
|
||||
|
||||
props.iconRight && child.push(
|
||||
h(QIcon, {
|
||||
class: 'q-chip__icon q-chip__icon--right',
|
||||
name: props.iconRight
|
||||
})
|
||||
)
|
||||
|
||||
props.removable === true && child.push(
|
||||
h(QIcon, {
|
||||
class: 'q-chip__icon q-chip__icon--remove cursor-pointer',
|
||||
name: removeIcon.value,
|
||||
...attributes.value.remove,
|
||||
onClick: onRemove,
|
||||
onKeyup: onRemove
|
||||
})
|
||||
)
|
||||
|
||||
return child
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (props.modelValue === false) return
|
||||
|
||||
const data = {
|
||||
class: classes.value,
|
||||
style: sizeStyle.value
|
||||
}
|
||||
|
||||
isClickable.value === true && Object.assign(
|
||||
data,
|
||||
attributes.value.chip,
|
||||
{ onClick, onKeyup }
|
||||
)
|
||||
|
||||
return hDir(
|
||||
'div',
|
||||
data,
|
||||
getContent(),
|
||||
'ripple',
|
||||
props.ripple !== false && props.disable !== true,
|
||||
() => [ [ Ripple, props.ripple ] ]
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
154
Frontend-Learner/node_modules/quasar/src/components/chip/QChip.json
generated
vendored
Normal file
154
Frontend-Learner/node_modules/quasar/src/components/chip/QChip.json
generated
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/chip"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"dense": {
|
||||
"extends": "dense"
|
||||
},
|
||||
|
||||
"size": {
|
||||
"type": "String",
|
||||
"desc": "QChip size name or a CSS unit including unit name",
|
||||
"examples": [ "'xs'", "'sm'", "'md'", "'lg'", "'xl'", "'25px'", "'2rem'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"dark": {
|
||||
"extends": "dark"
|
||||
},
|
||||
|
||||
"icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"icon-right": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"icon-remove": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"icon-selected": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"label": {
|
||||
"type": [ "String", "Number" ],
|
||||
"desc": "Chip's content as string; overrides default slot if specified",
|
||||
"examples": [ "'John Doe'", "'Book'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"text-color": {
|
||||
"extends": "text-color"
|
||||
},
|
||||
|
||||
"model-value": {
|
||||
"extends": "model-value",
|
||||
"type": "Boolean",
|
||||
"desc": "Model of the component determining if QChip should be rendered or not",
|
||||
"required": false,
|
||||
"default": "true"
|
||||
},
|
||||
|
||||
"selected": {
|
||||
"type": [ "Boolean", "null" ],
|
||||
"default": "null",
|
||||
"sync": true,
|
||||
"desc": "Model for QChip if it's selected or not",
|
||||
"examples": [ "# v-model:selected=\"myState\"" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"square": {
|
||||
"extends": "square",
|
||||
"desc": "Sets a low value for border-radius instead of the default one, making it close to a square"
|
||||
},
|
||||
|
||||
"outline": {
|
||||
"type": "Boolean",
|
||||
"desc": "Display using the 'outline' design",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"clickable": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is QChip clickable? If it's the case, then it will add hover effects and emit 'click' events",
|
||||
"category": "state"
|
||||
},
|
||||
|
||||
"removable": {
|
||||
"type": "Boolean",
|
||||
"desc": "If set, then it displays a 'remove' icon that when clicked the QChip emits 'remove' event",
|
||||
"category": "state"
|
||||
},
|
||||
|
||||
"ripple": {
|
||||
"extends": "ripple"
|
||||
},
|
||||
|
||||
"remove-aria-label": {
|
||||
"type": "String",
|
||||
"desc": "aria-label to be used on the remove icon",
|
||||
"examples": [ "'Remove item'" ],
|
||||
"category": "accessibility",
|
||||
"addedIn": "v2.8.4"
|
||||
},
|
||||
|
||||
"tabindex": {
|
||||
"extends": "tabindex"
|
||||
},
|
||||
|
||||
"disable": {
|
||||
"extends": "disable"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "This is where QChip content goes, if not using 'label' property"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"click": {
|
||||
"desc": "Emitted on QChip click if 'clickable' property is set",
|
||||
"params": {
|
||||
"evt": {
|
||||
"extends": "evt"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"update:model-value": {
|
||||
"extends": "update:model-value"
|
||||
},
|
||||
|
||||
"update:selected": {
|
||||
"desc": "Used by Vue on 'v-model:selected' for updating its value",
|
||||
"params": {
|
||||
"state": {
|
||||
"type": "Boolean",
|
||||
"desc": "Selected state"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"remove": {
|
||||
"desc": "Works along with 'value' and 'removable' prop. Emitted when toggling rendering state of the QChip",
|
||||
"params": {
|
||||
"state": {
|
||||
"type": "Boolean",
|
||||
"desc": "Render state (render or not)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Frontend-Learner/node_modules/quasar/src/components/chip/QChip.sass
generated
vendored
Normal file
89
Frontend-Learner/node_modules/quasar/src/components/chip/QChip.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
.q-chip
|
||||
vertical-align: middle
|
||||
border-radius: 16px
|
||||
outline: 0
|
||||
position: relative
|
||||
|
||||
height: $chip-height
|
||||
max-width: 100%
|
||||
margin: 4px
|
||||
|
||||
background: #e0e0e0
|
||||
color: rgba(0,0,0,.87)
|
||||
|
||||
font-size: $chip-font-size
|
||||
padding: .5em .9em
|
||||
|
||||
&--colored, &--dark
|
||||
.q-chip__icon
|
||||
color: inherit
|
||||
|
||||
.q-avatar
|
||||
font-size: $chip-avatar-font-size
|
||||
margin-left: -.45em
|
||||
margin-right: .2em
|
||||
border-radius: 16px
|
||||
|
||||
&--outline
|
||||
background: transparent !important
|
||||
border: 1px solid currentColor
|
||||
|
||||
.q-avatar
|
||||
// half padding and border width:
|
||||
margin-left: calc(-.45em - 1px)
|
||||
|
||||
&--selected
|
||||
.q-avatar
|
||||
display: none
|
||||
|
||||
&__icon
|
||||
color: rgba(0,0,0,.54)
|
||||
font-size: 1.5em
|
||||
margin: -.2em
|
||||
|
||||
&--left
|
||||
margin-right: .2em
|
||||
&--right
|
||||
margin-left: .2em
|
||||
&--remove
|
||||
margin-left: .1em
|
||||
margin-right: -.5em
|
||||
opacity: .6
|
||||
outline: 0
|
||||
|
||||
&:hover,
|
||||
&:focus
|
||||
opacity: 1
|
||||
|
||||
&__content
|
||||
white-space: nowrap
|
||||
|
||||
&--dense
|
||||
border-radius: 12px
|
||||
padding: 0 .4em
|
||||
height: $chip-dense-height
|
||||
|
||||
.q-avatar
|
||||
font-size: $chip-dense-avatar-font-size
|
||||
margin-left: -.27em
|
||||
margin-right: .1em
|
||||
border-radius: 12px
|
||||
|
||||
.q-chip__icon
|
||||
font-size: 1.25em
|
||||
&--left
|
||||
margin-right: .195em
|
||||
&--remove
|
||||
margin-right: -.25em
|
||||
|
||||
&--square
|
||||
border-radius: $generic-border-radius
|
||||
.q-avatar
|
||||
border-radius: ($generic-border-radius - 1px) 0 0 ($generic-border-radius - 1px)
|
||||
|
||||
body.desktop
|
||||
.q-chip--clickable:focus
|
||||
box-shadow: $shadow-1
|
||||
&.body--dark
|
||||
.q-chip--clickable:focus
|
||||
box-shadow: $dark-shadow-1
|
||||
794
Frontend-Learner/node_modules/quasar/src/components/chip/QChip.test.js
generated
vendored
Normal file
794
Frontend-Learner/node_modules/quasar/src/components/chip/QChip.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,794 @@
|
|||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
import QChip, { defaultSizes } from './QChip.js'
|
||||
|
||||
describe('[QChip API]', () => {
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)dense]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--dense')
|
||||
|
||||
await wrapper.setProps({ dense: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-chip--dense')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)size]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.$style('font-size')
|
||||
).not.toBe('100px')
|
||||
|
||||
await wrapper.setProps({ size: '100px' })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.$style('font-size')
|
||||
).toBe('100px')
|
||||
|
||||
await wrapper.setProps({ size: 'sm' })
|
||||
|
||||
expect(
|
||||
target.$style('font-size')
|
||||
).toBe(`${ defaultSizes.sm }px`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)dark]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--dark')
|
||||
|
||||
await wrapper.setProps({ dark: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-chip--dark')
|
||||
})
|
||||
|
||||
test('type null has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--dense')
|
||||
|
||||
await wrapper.setProps({ dark: null })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--dense')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)icon]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'map'
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-icon').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ icon: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-icon').text()
|
||||
).toContain(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)icon-right]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'map'
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-icon').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ iconRight: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-icon').text()
|
||||
).toContain(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)icon-remove]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'map'
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-icon').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({
|
||||
removable: true,
|
||||
iconRemove: propVal
|
||||
})
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-icon.q-chip__icon--remove')
|
||||
.text()
|
||||
).toBe(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)icon-selected]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'map'
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-icon').exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({
|
||||
selected: true,
|
||||
iconSelected: propVal
|
||||
})
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-chip.q-chip--selected')
|
||||
.get('.q-icon')
|
||||
.text()
|
||||
).toBe(propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)label]', () => {
|
||||
test.each([
|
||||
[ 'String', 'John Doe' ],
|
||||
[ 'Number', 22 ]
|
||||
])('type %s has effect', async (_, propVal) => {
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-chip__content')
|
||||
.text()
|
||||
).not.toBe('' + propVal)
|
||||
|
||||
await wrapper.setProps({ label: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-chip__content')
|
||||
.text()
|
||||
).toBe('' + propVal)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)color]', () => {
|
||||
test('with default design', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
let cls = target.classes()
|
||||
expect(cls).not.toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
|
||||
await wrapper.setProps({ color: propVal })
|
||||
await flushPromises()
|
||||
|
||||
cls = target.classes()
|
||||
expect(cls).not.toContain('text-red')
|
||||
expect(cls).toContain('bg-red')
|
||||
})
|
||||
|
||||
test('with outline design', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
outline: true
|
||||
}
|
||||
})
|
||||
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
let cls = target.classes()
|
||||
expect(cls).not.toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
|
||||
await wrapper.setProps({ color: propVal })
|
||||
await flushPromises()
|
||||
|
||||
cls = target.classes()
|
||||
expect(cls).toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)text-color]', () => {
|
||||
test('with default design', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
let cls = target.classes()
|
||||
expect(cls).not.toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
expect(cls).not.toContain('q-chip--colored')
|
||||
|
||||
await wrapper.setProps({ textColor: propVal })
|
||||
await flushPromises()
|
||||
|
||||
cls = target.classes()
|
||||
expect(cls).toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
expect(cls).toContain('q-chip--colored')
|
||||
})
|
||||
|
||||
test('with default design + color', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
color: 'blue'
|
||||
}
|
||||
})
|
||||
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
let cls = target.classes()
|
||||
expect(cls).not.toContain('text-blue')
|
||||
expect(cls).toContain('bg-blue')
|
||||
expect(cls).not.toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
expect(cls).not.toContain('q-chip--colored')
|
||||
|
||||
await wrapper.setProps({ textColor: propVal })
|
||||
await flushPromises()
|
||||
|
||||
cls = target.classes()
|
||||
expect(cls).not.toContain('text-blue')
|
||||
expect(cls).toContain('bg-blue')
|
||||
expect(cls).toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
expect(cls).toContain('q-chip--colored')
|
||||
})
|
||||
|
||||
test('with outline design', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
outline: true
|
||||
}
|
||||
})
|
||||
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
let cls = target.classes()
|
||||
expect(cls).not.toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
expect(cls).not.toContain('q-chip--colored')
|
||||
|
||||
await wrapper.setProps({ textColor: propVal })
|
||||
await flushPromises()
|
||||
|
||||
cls = target.classes()
|
||||
expect(cls).toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
expect(cls).toContain('q-chip--colored')
|
||||
})
|
||||
|
||||
test('with outline design + color', async () => {
|
||||
const propVal = 'red'
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
color: 'blue',
|
||||
outline: true
|
||||
}
|
||||
})
|
||||
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
let cls = target.classes()
|
||||
expect(cls).not.toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
expect(cls).toContain('text-blue')
|
||||
expect(cls).not.toContain('bg-blue')
|
||||
expect(cls).toContain('q-chip--colored')
|
||||
|
||||
await wrapper.setProps({ textColor: propVal })
|
||||
await flushPromises()
|
||||
|
||||
cls = target.classes()
|
||||
expect(cls).toContain('text-blue')
|
||||
expect(cls).not.toContain('bg-blue')
|
||||
expect(cls).not.toContain('text-red')
|
||||
expect(cls).not.toContain('bg-red')
|
||||
expect(cls).toContain('q-chip--colored')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)model-value]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
modelValue: true
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-chip').exists()
|
||||
).toBe(true)
|
||||
|
||||
await wrapper.setProps({ modelValue: false })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-chip')
|
||||
.exists()
|
||||
).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)selected]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--selected')
|
||||
|
||||
await wrapper.setProps({
|
||||
selected: true,
|
||||
'onUpdate:selected': val => { wrapper.setProps({ selected: val }) }
|
||||
})
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-chip--selected')
|
||||
})
|
||||
|
||||
test('type null has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--selected')
|
||||
|
||||
await wrapper.setProps({
|
||||
selected: null,
|
||||
'onUpdate:selected': val => { wrapper.setProps({ selected: val }) }
|
||||
})
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--selected')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)square]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--square')
|
||||
|
||||
await wrapper.setProps({ square: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-chip--square')
|
||||
|
||||
expect(
|
||||
target.$computedStyle('border-radius')
|
||||
).toBe('4px')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)outline]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).not.toContain('q-chip--outline')
|
||||
|
||||
await wrapper.setProps({ outline: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.classes()
|
||||
).toContain('q-chip--outline')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)clickable]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
const target = wrapper.get('.q-chip')
|
||||
|
||||
expect(
|
||||
target.attributes('tabindex')
|
||||
).toBeUndefined()
|
||||
|
||||
await wrapper.setProps({ clickable: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
target.attributes('tabindex')
|
||||
).toBe('0')
|
||||
|
||||
expect(
|
||||
target.$computedStyle('cursor')
|
||||
).toBe('pointer')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)removable]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-icon.q-chip__icon--remove')
|
||||
.exists()
|
||||
).not.toBe(true)
|
||||
|
||||
await wrapper.setProps({ removable: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-icon.q-chip__icon--remove')
|
||||
.exists()
|
||||
).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)ripple]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-ripple')
|
||||
.exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ ripple: true })
|
||||
await flushPromises()
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-ripple')
|
||||
.exists()
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
test('type Object has effect', async () => {
|
||||
const propVal = { center: true, color: 'teal', keyCodes: [] }
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-ripple')
|
||||
.exists()
|
||||
).toBe(false)
|
||||
|
||||
await wrapper.setProps({ ripple: propVal })
|
||||
await flushPromises()
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
expect(
|
||||
wrapper.find('.q-ripple')
|
||||
.exists()
|
||||
).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)remove-aria-label]', () => {
|
||||
test('type String has effect', async () => {
|
||||
const propVal = 'Remove item'
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
removable: true
|
||||
}
|
||||
})
|
||||
|
||||
const removeIcon = wrapper.get('.q-chip__icon--remove')
|
||||
|
||||
expect(
|
||||
removeIcon.attributes('aria-label')
|
||||
).not.toBe(propVal)
|
||||
|
||||
await wrapper.setProps({ removeAriaLabel: propVal })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
removeIcon.attributes('aria-label')
|
||||
).toBe(propVal)
|
||||
|
||||
expect(
|
||||
removeIcon.attributes('tabindex')
|
||||
).toBe('0')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)tabindex]', () => {
|
||||
test.each([
|
||||
[ 'Number', 100 ],
|
||||
[ 'String', '100' ]
|
||||
])('type %s has effect', async (_, propVal) => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
clickable: true,
|
||||
tabindex: propVal
|
||||
}
|
||||
})
|
||||
|
||||
expect(
|
||||
wrapper.attributes('tabindex')
|
||||
).toBe('' + propVal)
|
||||
|
||||
// we'll test clickable + disable
|
||||
await wrapper.setProps({ disable: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.attributes('tabindex')
|
||||
).toBeUndefined()
|
||||
|
||||
expect(
|
||||
wrapper.attributes('aria-disabled')
|
||||
).toBeUndefined()
|
||||
|
||||
// we'll now test removable + disable
|
||||
await wrapper.setProps({
|
||||
clickable: false,
|
||||
removable: true
|
||||
})
|
||||
await flushPromises()
|
||||
|
||||
let removeIcon = wrapper.get('.q-chip__icon--remove')
|
||||
|
||||
expect(
|
||||
removeIcon.attributes('tabindex')
|
||||
).toBe('-1')
|
||||
|
||||
expect(
|
||||
removeIcon.attributes('aria-disabled')
|
||||
).toBe('true')
|
||||
|
||||
// we'll now test removable
|
||||
await wrapper.setProps({ disable: false })
|
||||
await flushPromises()
|
||||
|
||||
removeIcon = wrapper.get('.q-chip__icon--remove')
|
||||
|
||||
expect(
|
||||
removeIcon.attributes('tabindex')
|
||||
).toBe('' + propVal)
|
||||
|
||||
expect(
|
||||
removeIcon.attributes('aria-disabled')
|
||||
).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)disable]', () => {
|
||||
test('type Boolean has effect', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-chip').classes()
|
||||
).not.toContain('disabled')
|
||||
|
||||
await wrapper.setProps({ disable: true })
|
||||
await flushPromises()
|
||||
|
||||
expect(
|
||||
wrapper.get('.q-chip').classes()
|
||||
).toContain('disabled')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Slots]', () => {
|
||||
describe('[(slot)default]', () => {
|
||||
test('renders the content', () => {
|
||||
const slotContent = 'some-slot-content'
|
||||
const wrapper = mount(QChip, {
|
||||
slots: {
|
||||
default: () => slotContent
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.text()).toContain(slotContent)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Events]', () => {
|
||||
describe('[(event)click]', () => {
|
||||
test('is emitting when clickable', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
clickable: true
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).toHaveProperty('click')
|
||||
expect(eventList.click).toHaveLength(1)
|
||||
|
||||
const [ evt ] = eventList.click[ 0 ]
|
||||
expect(evt).toBeInstanceOf(Event)
|
||||
})
|
||||
|
||||
test('is emitting when selected', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
selected: true
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).toHaveProperty('click')
|
||||
expect(eventList.click).toHaveLength(1)
|
||||
|
||||
const [ evt ] = eventList.click[ 0 ]
|
||||
expect(evt).toBeInstanceOf(Event)
|
||||
})
|
||||
|
||||
test('is NOT emitting when not clickable or removable', async () => {
|
||||
const wrapper = mount(QChip)
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).not.toHaveProperty('click')
|
||||
})
|
||||
|
||||
test('is NOT emitting when disable + clickable', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
clickable: true,
|
||||
disable: true
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).not.toHaveProperty('click')
|
||||
})
|
||||
|
||||
test('is NOT emitting when disable + selected', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
selected: true,
|
||||
disable: true
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).not.toHaveProperty('click')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(event)update:selected]', () => {
|
||||
test('is emitting', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
selected: false,
|
||||
'onUpdate:selected': val => {
|
||||
wrapper.setProps({ selected: val })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).toHaveProperty('update:selected')
|
||||
expect(eventList[ 'update:selected' ]).toHaveLength(1)
|
||||
|
||||
const [ state ] = eventList[ 'update:selected' ][ 0 ]
|
||||
expect(state).toBeTypeOf('boolean')
|
||||
})
|
||||
|
||||
test('is NOT emitting when disable', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
disable: true,
|
||||
selected: false,
|
||||
'onUpdate:selected': val => {
|
||||
wrapper.setProps({ selected: val })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).not.toHaveProperty('update:selected')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(event)remove]', () => {
|
||||
test('is emitting', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
removable: true
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.get('.q-chip__icon--remove')
|
||||
.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).toHaveProperty('remove')
|
||||
expect(eventList.remove).toHaveLength(1)
|
||||
|
||||
expect(eventList.remove[ 0 ]).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(event)update:model-value]', () => {
|
||||
test('is emitting', async () => {
|
||||
const wrapper = mount(QChip, {
|
||||
props: {
|
||||
removable: true,
|
||||
modelValue: true,
|
||||
'onUpdate:modelValue': val => {
|
||||
wrapper.setProps({ modelValue: val })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.get('.q-chip__icon--remove')
|
||||
.trigger('click')
|
||||
|
||||
const eventList = wrapper.emitted()
|
||||
expect(eventList).toHaveProperty('update:modelValue')
|
||||
expect(eventList[ 'update:modelValue' ]).toHaveLength(1)
|
||||
|
||||
const [ value ] = eventList[ 'update:modelValue' ][ 0 ]
|
||||
expect(value).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/chip/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/chip/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QChip from './QChip.js'
|
||||
|
||||
export {
|
||||
QChip
|
||||
}
|
||||
148
Frontend-Learner/node_modules/quasar/src/components/circular-progress/QCircularProgress.js
generated
vendored
Normal file
148
Frontend-Learner/node_modules/quasar/src/components/circular-progress/QCircularProgress.js
generated
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
import { h, computed, getCurrentInstance } from 'vue'
|
||||
|
||||
import useSize from '../../composables/private.use-size/use-size.js'
|
||||
import { useCircularCommonProps } from './circular-progress.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { hMergeSlotSafely } from '../../utils/private.render/render.js'
|
||||
import { between } from '../../utils/format/format.js'
|
||||
|
||||
const
|
||||
radius = 50,
|
||||
diameter = 2 * radius,
|
||||
circumference = diameter * Math.PI,
|
||||
strokeDashArray = Math.round(circumference * 1000) / 1000
|
||||
|
||||
export default createComponent({
|
||||
name: 'QCircularProgress',
|
||||
|
||||
props: {
|
||||
...useCircularCommonProps,
|
||||
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
|
||||
animationSpeed: {
|
||||
type: [ String, Number ],
|
||||
default: 600
|
||||
},
|
||||
|
||||
indeterminate: Boolean
|
||||
},
|
||||
|
||||
setup (props, { slots }) {
|
||||
const { proxy: { $q } } = getCurrentInstance()
|
||||
const sizeStyle = useSize(props)
|
||||
|
||||
const svgStyle = computed(() => {
|
||||
const angle = ($q.lang.rtl === true ? -1 : 1) * props.angle
|
||||
|
||||
return {
|
||||
transform: props.reverse !== ($q.lang.rtl === true)
|
||||
? `scale3d(-1, 1, 1) rotate3d(0, 0, 1, ${ -90 - angle }deg)`
|
||||
: `rotate3d(0, 0, 1, ${ angle - 90 }deg)`
|
||||
}
|
||||
})
|
||||
|
||||
const circleStyle = computed(() => (
|
||||
props.instantFeedback !== true && props.indeterminate !== true
|
||||
? { transition: `stroke-dashoffset ${ props.animationSpeed }ms ease 0s, stroke ${ props.animationSpeed }ms ease` }
|
||||
: ''
|
||||
))
|
||||
|
||||
const viewBox = computed(() => diameter / (1 - props.thickness / 2))
|
||||
|
||||
const viewBoxAttr = computed(() =>
|
||||
`${ viewBox.value / 2 } ${ viewBox.value / 2 } ${ viewBox.value } ${ viewBox.value }`
|
||||
)
|
||||
|
||||
const normalized = computed(() => between(props.value, props.min, props.max))
|
||||
|
||||
const range = computed(() => props.max - props.min)
|
||||
const strokeWidth = computed(() => props.thickness / 2 * viewBox.value)
|
||||
const strokeDashOffset = computed(() => {
|
||||
const dashRatio = (props.max - normalized.value) / range.value
|
||||
const dashGap = props.rounded === true && normalized.value < props.max && dashRatio < 0.25
|
||||
? strokeWidth.value / 2 * (1 - dashRatio / 0.25)
|
||||
: 0
|
||||
|
||||
return circumference * dashRatio + dashGap
|
||||
})
|
||||
|
||||
function getCircle ({ thickness, offset, color, cls, rounded }) {
|
||||
return h('circle', {
|
||||
class: 'q-circular-progress__' + cls + (color !== void 0 ? ` text-${ color }` : ''),
|
||||
style: circleStyle.value,
|
||||
fill: 'transparent',
|
||||
stroke: 'currentColor',
|
||||
'stroke-width': thickness,
|
||||
'stroke-dasharray': strokeDashArray,
|
||||
'stroke-dashoffset': offset,
|
||||
'stroke-linecap': rounded,
|
||||
cx: viewBox.value,
|
||||
cy: viewBox.value,
|
||||
r: radius
|
||||
})
|
||||
}
|
||||
|
||||
return () => {
|
||||
const svgChild = []
|
||||
|
||||
props.centerColor !== void 0 && props.centerColor !== 'transparent' && svgChild.push(
|
||||
h('circle', {
|
||||
class: `q-circular-progress__center text-${ props.centerColor }`,
|
||||
fill: 'currentColor',
|
||||
r: radius - strokeWidth.value / 2,
|
||||
cx: viewBox.value,
|
||||
cy: viewBox.value
|
||||
})
|
||||
)
|
||||
|
||||
props.trackColor !== void 0 && props.trackColor !== 'transparent' && svgChild.push(
|
||||
getCircle({
|
||||
cls: 'track',
|
||||
thickness: strokeWidth.value,
|
||||
offset: 0,
|
||||
color: props.trackColor
|
||||
})
|
||||
)
|
||||
|
||||
svgChild.push(
|
||||
getCircle({
|
||||
cls: 'circle',
|
||||
thickness: strokeWidth.value,
|
||||
offset: strokeDashOffset.value,
|
||||
color: props.color,
|
||||
rounded: props.rounded === true ? 'round' : void 0
|
||||
})
|
||||
)
|
||||
|
||||
const child = [
|
||||
h('svg', {
|
||||
class: 'q-circular-progress__svg',
|
||||
style: svgStyle.value,
|
||||
viewBox: viewBoxAttr.value,
|
||||
'aria-hidden': 'true'
|
||||
}, svgChild)
|
||||
]
|
||||
|
||||
props.showValue === true && child.push(
|
||||
h('div', {
|
||||
class: 'q-circular-progress__text absolute-full row flex-center content-center',
|
||||
style: { fontSize: props.fontSize }
|
||||
}, slots.default !== void 0 ? slots.default() : [ h('div', normalized.value) ])
|
||||
)
|
||||
|
||||
return h('div', {
|
||||
class: `q-circular-progress q-circular-progress--${ props.indeterminate === true ? 'in' : '' }determinate`,
|
||||
style: sizeStyle.value,
|
||||
role: 'progressbar',
|
||||
'aria-valuemin': props.min,
|
||||
'aria-valuemax': props.max,
|
||||
'aria-valuenow': props.indeterminate === true ? void 0 : normalized.value
|
||||
}, hMergeSlotSafely(slots.internal, child)) // "internal" is used by QKnob
|
||||
}
|
||||
}
|
||||
})
|
||||
114
Frontend-Learner/node_modules/quasar/src/components/circular-progress/QCircularProgress.json
generated
vendored
Normal file
114
Frontend-Learner/node_modules/quasar/src/components/circular-progress/QCircularProgress.json
generated
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
{
|
||||
"mixins": [ "composables/private.use-size/use-size" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/circular-progress"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"default": "0",
|
||||
"desc": "Current progress (must be between min/max)",
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"min": {
|
||||
"type": "Number",
|
||||
"default": "0",
|
||||
"desc": "Minimum value defining 'no progress' (must be lower than 'max')",
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"max": {
|
||||
"type": "Number",
|
||||
"default": "100",
|
||||
"desc": "Maximum value defining 100% progress made (must be higher than 'min')",
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for the arc progress from the Quasar Color Palette"
|
||||
},
|
||||
|
||||
"center-color": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for the center part of the component from the Quasar Color Palette"
|
||||
},
|
||||
|
||||
"track-color": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for the track of the component from the Quasar Color Palette"
|
||||
},
|
||||
|
||||
"font-size": {
|
||||
"type": "String",
|
||||
"desc": "Size of text in CSS units, including unit name. Suggestion: use 'em' units to sync with component size",
|
||||
"examples": [ "'1em'", "'16px'", "'2rem'" ],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"rounded": {
|
||||
"type": "Boolean",
|
||||
"desc": "Rounding the arc of progress",
|
||||
"category": "style",
|
||||
"addedIn": "v2.8.4"
|
||||
},
|
||||
|
||||
"thickness": {
|
||||
"type": "Number",
|
||||
"default": "0.2",
|
||||
"desc": "Thickness of progress arc as a ratio (0.0 < x < 1.0) of component size",
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"angle": {
|
||||
"type": "Number",
|
||||
"desc": "Angle to rotate progress arc by",
|
||||
"default": "0",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"indeterminate": {
|
||||
"type": "Boolean",
|
||||
"desc": "Put component into 'indeterminate' state; Ignores 'value' prop",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"show-value": {
|
||||
"type": "Boolean",
|
||||
"desc": "Enables the default slot and uses it (if available), otherwise it displays the 'value' prop as text; Make sure the text has enough space to be displayed inside the component",
|
||||
"category": "content|behavior"
|
||||
},
|
||||
|
||||
"reverse": {
|
||||
"type": "Boolean",
|
||||
"desc": "Reverses the direction of progress; Only for determined state",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"instant-feedback": {
|
||||
"type": "Boolean",
|
||||
"desc": "No animation when model changes",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"animation-speed": {
|
||||
"extends": "animation-speed",
|
||||
"default": "600",
|
||||
"addedIn": "v2.3"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "Used for component content only if 'show-value' prop is set; Make sure the content has enough space to be displayed inside the component"
|
||||
},
|
||||
|
||||
"internal": {
|
||||
"desc": "Used by QKnob internally",
|
||||
"internal": true
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Frontend-Learner/node_modules/quasar/src/components/circular-progress/QCircularProgress.sass
generated
vendored
Normal file
38
Frontend-Learner/node_modules/quasar/src/components/circular-progress/QCircularProgress.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
.q-circular-progress
|
||||
display: inline-block
|
||||
position: relative
|
||||
vertical-align: middle
|
||||
|
||||
width: 1em
|
||||
height: 1em
|
||||
line-height: 1
|
||||
|
||||
&.q-focusable
|
||||
border-radius: 50%
|
||||
|
||||
&__svg
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
&__text
|
||||
font-size: .25em
|
||||
|
||||
&--indeterminate
|
||||
.q-circular-progress__svg
|
||||
transform-origin: 50% 50%
|
||||
animation: q-spin 2s linear infinite #{"/* rtl:ignore */"}
|
||||
.q-circular-progress__circle
|
||||
stroke-dasharray: 1 400
|
||||
stroke-dashoffset: 0
|
||||
animation: q-circular-progress-circle 1.5s ease-in-out infinite #{"/* rtl:ignore */"}
|
||||
|
||||
@keyframes q-circular-progress-circle
|
||||
0%
|
||||
stroke-dasharray: 1, 400
|
||||
stroke-dashoffset: 0
|
||||
50%
|
||||
stroke-dasharray: 400, 400
|
||||
stroke-dashoffset: -100
|
||||
100%
|
||||
stroke-dasharray: 400, 400
|
||||
stroke-dashoffset: -300
|
||||
39
Frontend-Learner/node_modules/quasar/src/components/circular-progress/circular-progress.js
generated
vendored
Normal file
39
Frontend-Learner/node_modules/quasar/src/components/circular-progress/circular-progress.js
generated
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { useSizeProps } from '../../composables/private.use-size/use-size.js'
|
||||
|
||||
// also used by QKnob
|
||||
export const useCircularCommonProps = {
|
||||
...useSizeProps,
|
||||
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
|
||||
color: String,
|
||||
centerColor: String,
|
||||
trackColor: String,
|
||||
|
||||
fontSize: String,
|
||||
rounded: Boolean,
|
||||
|
||||
// ratio
|
||||
thickness: {
|
||||
type: Number,
|
||||
default: 0.2,
|
||||
validator: v => v >= 0 && v <= 1
|
||||
},
|
||||
|
||||
angle: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
|
||||
showValue: Boolean,
|
||||
reverse: Boolean,
|
||||
|
||||
instantFeedback: Boolean
|
||||
}
|
||||
14
Frontend-Learner/node_modules/quasar/src/components/circular-progress/circular-progress.test.js
generated
vendored
Normal file
14
Frontend-Learner/node_modules/quasar/src/components/circular-progress/circular-progress.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
import { useCircularCommonProps } from './circular-progress.js'
|
||||
|
||||
describe('[circularProgress API]', () => {
|
||||
describe('[Variables]', () => {
|
||||
describe('[(variable)useCircularCommonProps]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(useCircularCommonProps).toBeTypeOf('object')
|
||||
expect(Object.keys(useCircularCommonProps)).not.toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/circular-progress/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/circular-progress/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QCircularProgress from './QCircularProgress.js'
|
||||
|
||||
export {
|
||||
QCircularProgress
|
||||
}
|
||||
851
Frontend-Learner/node_modules/quasar/src/components/color/QColor.js
generated
vendored
Normal file
851
Frontend-Learner/node_modules/quasar/src/components/color/QColor.js
generated
vendored
Normal file
|
|
@ -0,0 +1,851 @@
|
|||
import { h, ref, computed, watch, nextTick, getCurrentInstance } from 'vue'
|
||||
|
||||
import TouchPan from '../../directives/touch-pan/TouchPan.js'
|
||||
|
||||
import QSlider from '../slider/QSlider.js'
|
||||
import QIcon from '../icon/QIcon.js'
|
||||
|
||||
import QTabs from '../tabs/QTabs.js'
|
||||
import QTab from '../tabs/QTab.js'
|
||||
import QTabPanels from '../tab-panels/QTabPanels.js'
|
||||
import QTabPanel from '../tab-panels/QTabPanel.js'
|
||||
|
||||
import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js'
|
||||
import useRenderCache from '../../composables/use-render-cache/use-render-cache.js'
|
||||
import { useFormInject, useFormProps } from '../../composables/use-form/private.use-form.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { testPattern } from '../../utils/patterns/patterns.js'
|
||||
import throttle from '../../utils/throttle/throttle.js'
|
||||
import { stop } from '../../utils/event/event.js'
|
||||
import { hexToRgb, rgbToHex, rgbToString, textToRgb, rgbToHsv, hsvToRgb, luminosity } from '../../utils/colors/colors.js'
|
||||
import { hDir } from '../../utils/private.render/render.js'
|
||||
|
||||
const palette = [
|
||||
'rgb(255,204,204)', 'rgb(255,230,204)', 'rgb(255,255,204)', 'rgb(204,255,204)', 'rgb(204,255,230)', 'rgb(204,255,255)', 'rgb(204,230,255)', 'rgb(204,204,255)', 'rgb(230,204,255)', 'rgb(255,204,255)',
|
||||
'rgb(255,153,153)', 'rgb(255,204,153)', 'rgb(255,255,153)', 'rgb(153,255,153)', 'rgb(153,255,204)', 'rgb(153,255,255)', 'rgb(153,204,255)', 'rgb(153,153,255)', 'rgb(204,153,255)', 'rgb(255,153,255)',
|
||||
'rgb(255,102,102)', 'rgb(255,179,102)', 'rgb(255,255,102)', 'rgb(102,255,102)', 'rgb(102,255,179)', 'rgb(102,255,255)', 'rgb(102,179,255)', 'rgb(102,102,255)', 'rgb(179,102,255)', 'rgb(255,102,255)',
|
||||
'rgb(255,51,51)', 'rgb(255,153,51)', 'rgb(255,255,51)', 'rgb(51,255,51)', 'rgb(51,255,153)', 'rgb(51,255,255)', 'rgb(51,153,255)', 'rgb(51,51,255)', 'rgb(153,51,255)', 'rgb(255,51,255)',
|
||||
'rgb(255,0,0)', 'rgb(255,128,0)', 'rgb(255,255,0)', 'rgb(0,255,0)', 'rgb(0,255,128)', 'rgb(0,255,255)', 'rgb(0,128,255)', 'rgb(0,0,255)', 'rgb(128,0,255)', 'rgb(255,0,255)',
|
||||
'rgb(245,0,0)', 'rgb(245,123,0)', 'rgb(245,245,0)', 'rgb(0,245,0)', 'rgb(0,245,123)', 'rgb(0,245,245)', 'rgb(0,123,245)', 'rgb(0,0,245)', 'rgb(123,0,245)', 'rgb(245,0,245)',
|
||||
'rgb(214,0,0)', 'rgb(214,108,0)', 'rgb(214,214,0)', 'rgb(0,214,0)', 'rgb(0,214,108)', 'rgb(0,214,214)', 'rgb(0,108,214)', 'rgb(0,0,214)', 'rgb(108,0,214)', 'rgb(214,0,214)',
|
||||
'rgb(163,0,0)', 'rgb(163,82,0)', 'rgb(163,163,0)', 'rgb(0,163,0)', 'rgb(0,163,82)', 'rgb(0,163,163)', 'rgb(0,82,163)', 'rgb(0,0,163)', 'rgb(82,0,163)', 'rgb(163,0,163)',
|
||||
'rgb(92,0,0)', 'rgb(92,46,0)', 'rgb(92,92,0)', 'rgb(0,92,0)', 'rgb(0,92,46)', 'rgb(0,92,92)', 'rgb(0,46,92)', 'rgb(0,0,92)', 'rgb(46,0,92)', 'rgb(92,0,92)',
|
||||
'rgb(255,255,255)', 'rgb(205,205,205)', 'rgb(178,178,178)', 'rgb(153,153,153)', 'rgb(127,127,127)', 'rgb(102,102,102)', 'rgb(76,76,76)', 'rgb(51,51,51)', 'rgb(25,25,25)', 'rgb(0,0,0)'
|
||||
]
|
||||
|
||||
const thumbPath = 'M5 5 h10 v10 h-10 v-10 z'
|
||||
const alphaTrackImg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAH0lEQVQoU2NkYGAwZkAFZ5G5jPRRgOYEVDeB3EBjBQBOZwTVugIGyAAAAABJRU5ErkJggg=='
|
||||
|
||||
export default createComponent({
|
||||
name: 'QColor',
|
||||
|
||||
props: {
|
||||
...useDarkProps,
|
||||
...useFormProps,
|
||||
|
||||
modelValue: String,
|
||||
|
||||
defaultValue: String,
|
||||
defaultView: {
|
||||
type: String,
|
||||
default: 'spectrum',
|
||||
validator: v => [ 'spectrum', 'tune', 'palette' ].includes(v)
|
||||
},
|
||||
|
||||
formatModel: {
|
||||
type: String,
|
||||
default: 'auto',
|
||||
validator: v => [ 'auto', 'hex', 'rgb', 'hexa', 'rgba' ].includes(v)
|
||||
},
|
||||
|
||||
palette: Array,
|
||||
|
||||
noHeader: Boolean,
|
||||
noHeaderTabs: Boolean,
|
||||
noFooter: Boolean,
|
||||
|
||||
square: Boolean,
|
||||
flat: Boolean,
|
||||
bordered: Boolean,
|
||||
|
||||
disable: Boolean,
|
||||
readonly: Boolean
|
||||
},
|
||||
|
||||
emits: [ 'update:modelValue', 'change' ],
|
||||
|
||||
setup (props, { emit }) {
|
||||
const { proxy } = getCurrentInstance()
|
||||
const { $q } = proxy
|
||||
|
||||
const isDark = useDark(props, $q)
|
||||
const { getCache } = useRenderCache()
|
||||
|
||||
const spectrumRef = ref(null)
|
||||
const errorIconRef = ref(null)
|
||||
|
||||
const forceHex = computed(() => (
|
||||
props.formatModel === 'auto'
|
||||
? null
|
||||
: props.formatModel.indexOf('hex') !== -1
|
||||
))
|
||||
|
||||
const forceAlpha = computed(() => (
|
||||
props.formatModel === 'auto'
|
||||
? null
|
||||
: props.formatModel.indexOf('a') !== -1
|
||||
))
|
||||
|
||||
const topView = ref(
|
||||
props.formatModel === 'auto'
|
||||
? (
|
||||
(props.modelValue === void 0 || props.modelValue === null || props.modelValue === '' || props.modelValue.startsWith('#'))
|
||||
? 'hex'
|
||||
: 'rgb'
|
||||
)
|
||||
: (props.formatModel.startsWith('hex') ? 'hex' : 'rgb')
|
||||
)
|
||||
|
||||
const view = ref(props.defaultView)
|
||||
const model = ref(parseModel(props.modelValue || props.defaultValue))
|
||||
|
||||
const editable = computed(() => props.disable !== true && props.readonly !== true)
|
||||
|
||||
const isHex = computed(() =>
|
||||
props.modelValue === void 0
|
||||
|| props.modelValue === null
|
||||
|| props.modelValue === ''
|
||||
|| props.modelValue.startsWith('#')
|
||||
)
|
||||
|
||||
const isOutputHex = computed(() => (
|
||||
forceHex.value !== null
|
||||
? forceHex.value
|
||||
: isHex.value
|
||||
))
|
||||
|
||||
const formAttrs = computed(() => ({
|
||||
type: 'hidden',
|
||||
name: props.name,
|
||||
value: model.value[ isOutputHex.value === true ? 'hex' : 'rgb' ]
|
||||
}))
|
||||
|
||||
const injectFormInput = useFormInject(formAttrs)
|
||||
|
||||
const hasAlpha = computed(() => (
|
||||
forceAlpha.value !== null
|
||||
? forceAlpha.value
|
||||
: model.value.a !== void 0
|
||||
))
|
||||
|
||||
const currentBgColor = computed(() => ({
|
||||
backgroundColor: model.value.rgb || '#000'
|
||||
}))
|
||||
|
||||
const headerClass = computed(() => {
|
||||
const light = model.value.a !== void 0 && model.value.a < 65
|
||||
? true
|
||||
: luminosity(model.value) > 0.4
|
||||
|
||||
return 'q-color-picker__header-content'
|
||||
+ ` q-color-picker__header-content--${ light ? 'light' : 'dark' }`
|
||||
})
|
||||
|
||||
const spectrumStyle = computed(() => ({
|
||||
background: `hsl(${ model.value.h },100%,50%)`
|
||||
}))
|
||||
|
||||
const spectrumPointerStyle = computed(() => ({
|
||||
top: `${ 100 - model.value.v }%`,
|
||||
[ $q.lang.rtl === true ? 'right' : 'left' ]: `${ model.value.s }%`
|
||||
}))
|
||||
|
||||
const computedPalette = computed(() => (
|
||||
props.palette !== void 0 && props.palette.length !== 0
|
||||
? props.palette
|
||||
: palette
|
||||
))
|
||||
|
||||
const classes = computed(() =>
|
||||
'q-color-picker'
|
||||
+ (props.bordered === true ? ' q-color-picker--bordered' : '')
|
||||
+ (props.square === true ? ' q-color-picker--square no-border-radius' : '')
|
||||
+ (props.flat === true ? ' q-color-picker--flat no-shadow' : '')
|
||||
+ (props.disable === true ? ' disabled' : '')
|
||||
+ (isDark.value === true ? ' q-color-picker--dark q-dark' : '')
|
||||
)
|
||||
|
||||
const attributes = computed(() => (
|
||||
props.disable === true
|
||||
? { 'aria-disabled': 'true' }
|
||||
: {}
|
||||
))
|
||||
|
||||
const spectrumDirective = computed(() => {
|
||||
// if editable.value === true
|
||||
return [ [
|
||||
TouchPan,
|
||||
onSpectrumPan,
|
||||
void 0,
|
||||
{ prevent: true, stop: true, mouse: true }
|
||||
] ]
|
||||
})
|
||||
|
||||
watch(() => props.modelValue, v => {
|
||||
const localModel = parseModel(v || props.defaultValue)
|
||||
if (localModel.hex !== model.value.hex) {
|
||||
model.value = localModel
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.defaultValue, v => {
|
||||
if (!props.modelValue && v) {
|
||||
const localModel = parseModel(v)
|
||||
if (localModel.hex !== model.value.hex) {
|
||||
model.value = localModel
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function updateModel (rgb, change) {
|
||||
// update internally
|
||||
model.value.hex = rgbToHex(rgb)
|
||||
model.value.rgb = rgbToString(rgb)
|
||||
model.value.r = rgb.r
|
||||
model.value.g = rgb.g
|
||||
model.value.b = rgb.b
|
||||
model.value.a = rgb.a
|
||||
|
||||
const value = model.value[ isOutputHex.value === true ? 'hex' : 'rgb' ]
|
||||
|
||||
// emit new value
|
||||
emit('update:modelValue', value)
|
||||
change === true && emit('change', value)
|
||||
}
|
||||
|
||||
function parseModel (v) {
|
||||
const alpha = forceAlpha.value !== void 0
|
||||
? forceAlpha.value
|
||||
: (
|
||||
props.formatModel === 'auto'
|
||||
? null
|
||||
: props.formatModel.indexOf('a') !== -1
|
||||
)
|
||||
|
||||
if (typeof v !== 'string' || v.length === 0 || testPattern.anyColor(v.replace(/ /g, '')) !== true) {
|
||||
return {
|
||||
h: 0,
|
||||
s: 0,
|
||||
v: 0,
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: alpha === true ? 100 : void 0,
|
||||
hex: void 0,
|
||||
rgb: void 0
|
||||
}
|
||||
}
|
||||
|
||||
const model = textToRgb(v)
|
||||
|
||||
if (alpha === true && model.a === void 0) {
|
||||
model.a = 100
|
||||
}
|
||||
|
||||
model.hex = rgbToHex(model)
|
||||
model.rgb = rgbToString(model)
|
||||
|
||||
return Object.assign(model, rgbToHsv(model))
|
||||
}
|
||||
|
||||
function changeSpectrum (left, top, change) {
|
||||
const panel = spectrumRef.value
|
||||
if (panel === null) return
|
||||
|
||||
const
|
||||
width = panel.clientWidth,
|
||||
height = panel.clientHeight,
|
||||
rect = panel.getBoundingClientRect()
|
||||
|
||||
let x = Math.min(width, Math.max(0, left - rect.left))
|
||||
|
||||
if ($q.lang.rtl === true) {
|
||||
x = width - x
|
||||
}
|
||||
|
||||
const
|
||||
y = Math.min(height, Math.max(0, top - rect.top)),
|
||||
s = Math.round(100 * x / width),
|
||||
v = Math.round(100 * Math.max(0, Math.min(1, -(y / height) + 1))),
|
||||
rgb = hsvToRgb({
|
||||
h: model.value.h,
|
||||
s,
|
||||
v,
|
||||
a: hasAlpha.value === true ? model.value.a : void 0
|
||||
})
|
||||
|
||||
model.value.s = s
|
||||
model.value.v = v
|
||||
updateModel(rgb, change)
|
||||
}
|
||||
|
||||
function onHue (val, change) {
|
||||
const h = Math.round(val)
|
||||
const rgb = hsvToRgb({
|
||||
h,
|
||||
s: model.value.s,
|
||||
v: model.value.v,
|
||||
a: hasAlpha.value === true ? model.value.a : void 0
|
||||
})
|
||||
|
||||
model.value.h = h
|
||||
updateModel(rgb, change)
|
||||
}
|
||||
|
||||
function onHueChange (val) {
|
||||
onHue(val, true)
|
||||
}
|
||||
|
||||
function onNumericChange (value, formatModel, max, evt, change) {
|
||||
evt !== void 0 && stop(evt)
|
||||
|
||||
if (!/^[0-9]+$/.test(value)) {
|
||||
change === true && proxy.$forceUpdate()
|
||||
return
|
||||
}
|
||||
|
||||
const val = Math.floor(Number(value))
|
||||
|
||||
if (val < 0 || val > max) {
|
||||
change === true && proxy.$forceUpdate()
|
||||
return
|
||||
}
|
||||
|
||||
const rgb = {
|
||||
r: formatModel === 'r' ? val : model.value.r,
|
||||
g: formatModel === 'g' ? val : model.value.g,
|
||||
b: formatModel === 'b' ? val : model.value.b,
|
||||
a: hasAlpha.value === true
|
||||
? (formatModel === 'a' ? val : model.value.a)
|
||||
: void 0
|
||||
}
|
||||
|
||||
if (formatModel !== 'a') {
|
||||
const hsv = rgbToHsv(rgb)
|
||||
model.value.h = hsv.h
|
||||
model.value.s = hsv.s
|
||||
model.value.v = hsv.v
|
||||
}
|
||||
|
||||
updateModel(rgb, change)
|
||||
|
||||
if (change !== true && evt?.target.selectionEnd !== void 0) {
|
||||
const index = evt.target.selectionEnd
|
||||
nextTick(() => {
|
||||
evt.target.setSelectionRange(index, index)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function onEditorChange (evt, change) {
|
||||
let rgb
|
||||
const inp = evt.target.value
|
||||
|
||||
stop(evt)
|
||||
|
||||
if (topView.value === 'hex') {
|
||||
if (
|
||||
inp.length !== (hasAlpha.value === true ? 9 : 7)
|
||||
|| !/^#[0-9A-Fa-f]+$/.test(inp)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
rgb = hexToRgb(inp)
|
||||
}
|
||||
else {
|
||||
let model
|
||||
|
||||
if (!inp.endsWith(')')) {
|
||||
return true
|
||||
}
|
||||
else if (hasAlpha.value !== true && inp.startsWith('rgb(')) {
|
||||
model = inp.substring(4, inp.length - 1).split(',').map(n => parseInt(n, 10))
|
||||
|
||||
if (
|
||||
model.length !== 3
|
||||
|| !/^rgb\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\)$/.test(inp)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
else if (hasAlpha.value === true && inp.startsWith('rgba(')) {
|
||||
model = inp.substring(5, inp.length - 1).split(',')
|
||||
|
||||
if (
|
||||
model.length !== 4
|
||||
|| !/^rgba\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},(0|0\.[0-9]+[1-9]|0\.[1-9]+|1)\)$/.test(inp)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const v = parseInt(model[ i ], 10)
|
||||
if (v < 0 || v > 255) {
|
||||
return true
|
||||
}
|
||||
model[ i ] = v
|
||||
}
|
||||
|
||||
const v = parseFloat(model[ 3 ])
|
||||
if (v < 0 || v > 1) {
|
||||
return true
|
||||
}
|
||||
model[ 3 ] = v
|
||||
}
|
||||
else {
|
||||
return true
|
||||
}
|
||||
|
||||
if (
|
||||
model[ 0 ] < 0 || model[ 0 ] > 255
|
||||
|| model[ 1 ] < 0 || model[ 1 ] > 255
|
||||
|| model[ 2 ] < 0 || model[ 2 ] > 255
|
||||
|| (hasAlpha.value === true && (model[ 3 ] < 0 || model[ 3 ] > 1))
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
rgb = {
|
||||
r: model[ 0 ],
|
||||
g: model[ 1 ],
|
||||
b: model[ 2 ],
|
||||
a: hasAlpha.value === true
|
||||
? model[ 3 ] * 100
|
||||
: void 0
|
||||
}
|
||||
}
|
||||
|
||||
const hsv = rgbToHsv(rgb)
|
||||
model.value.h = hsv.h
|
||||
model.value.s = hsv.s
|
||||
model.value.v = hsv.v
|
||||
|
||||
updateModel(rgb, change)
|
||||
|
||||
if (change !== true) {
|
||||
const index = evt.target.selectionEnd
|
||||
nextTick(() => {
|
||||
evt.target.setSelectionRange(index, index)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function onPalettePick (color) {
|
||||
const def = parseModel(color)
|
||||
const rgb = { r: def.r, g: def.g, b: def.b, a: def.a }
|
||||
|
||||
if (rgb.a === void 0) {
|
||||
rgb.a = model.value.a
|
||||
}
|
||||
|
||||
model.value.h = def.h
|
||||
model.value.s = def.s
|
||||
model.value.v = def.v
|
||||
|
||||
updateModel(rgb, true)
|
||||
}
|
||||
|
||||
function onSpectrumPan (evt) {
|
||||
if (evt.isFinal) {
|
||||
changeSpectrum(
|
||||
evt.position.left,
|
||||
evt.position.top,
|
||||
true
|
||||
)
|
||||
}
|
||||
else {
|
||||
onSpectrumChange(evt)
|
||||
}
|
||||
}
|
||||
|
||||
const onSpectrumChange = throttle(
|
||||
evt => { changeSpectrum(evt.position.left, evt.position.top) },
|
||||
20
|
||||
)
|
||||
|
||||
function onSpectrumClick (evt) {
|
||||
changeSpectrum(
|
||||
evt.pageX - window.pageXOffset,
|
||||
evt.pageY - window.pageYOffset,
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
function onActivate (evt) {
|
||||
changeSpectrum(
|
||||
evt.pageX - window.pageXOffset,
|
||||
evt.pageY - window.pageYOffset
|
||||
)
|
||||
}
|
||||
|
||||
function updateErrorIcon (val) {
|
||||
// we MUST avoid vue triggering a render,
|
||||
// so manually changing this
|
||||
if (errorIconRef.value !== null) {
|
||||
errorIconRef.value.$el.style.opacity = val ? 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
function setTopView (val) {
|
||||
topView.value = val
|
||||
}
|
||||
|
||||
function getHeader () {
|
||||
const child = []
|
||||
|
||||
props.noHeaderTabs !== true && child.push(
|
||||
h(QTabs, {
|
||||
class: 'q-color-picker__header-tabs',
|
||||
modelValue: topView.value,
|
||||
dense: true,
|
||||
align: 'justify',
|
||||
'onUpdate:modelValue': setTopView
|
||||
}, () => [
|
||||
h(QTab, {
|
||||
label: 'HEX' + (hasAlpha.value === true ? 'A' : ''),
|
||||
name: 'hex',
|
||||
ripple: false
|
||||
}),
|
||||
|
||||
h(QTab, {
|
||||
label: 'RGB' + (hasAlpha.value === true ? 'A' : ''),
|
||||
name: 'rgb',
|
||||
ripple: false
|
||||
})
|
||||
])
|
||||
)
|
||||
|
||||
child.push(
|
||||
h('div', {
|
||||
class: 'q-color-picker__header-banner row flex-center no-wrap'
|
||||
}, [
|
||||
h('input', {
|
||||
class: 'fit',
|
||||
value: model.value[ topView.value ],
|
||||
...(editable.value !== true
|
||||
? { readonly: true }
|
||||
: {}
|
||||
),
|
||||
...getCache('topIn', {
|
||||
onInput: evt => {
|
||||
updateErrorIcon(onEditorChange(evt) === true)
|
||||
},
|
||||
onChange: stop,
|
||||
onBlur: evt => {
|
||||
onEditorChange(evt, true) === true && proxy.$forceUpdate()
|
||||
updateErrorIcon(false)
|
||||
}
|
||||
})
|
||||
}),
|
||||
|
||||
h(QIcon, {
|
||||
ref: errorIconRef,
|
||||
class: 'q-color-picker__error-icon absolute no-pointer-events',
|
||||
name: $q.iconSet.type.negative
|
||||
})
|
||||
])
|
||||
)
|
||||
|
||||
return h('div', {
|
||||
class: 'q-color-picker__header relative-position overflow-hidden'
|
||||
}, [
|
||||
h('div', { class: 'q-color-picker__header-bg absolute-full' }),
|
||||
|
||||
h('div', {
|
||||
class: headerClass.value,
|
||||
style: currentBgColor.value
|
||||
}, child)
|
||||
])
|
||||
}
|
||||
|
||||
function getContent () {
|
||||
return h(QTabPanels, {
|
||||
modelValue: view.value,
|
||||
animated: true
|
||||
}, () => [
|
||||
h(QTabPanel, {
|
||||
class: 'q-color-picker__spectrum-tab overflow-hidden',
|
||||
name: 'spectrum'
|
||||
}, getSpectrumTab),
|
||||
|
||||
h(QTabPanel, {
|
||||
class: 'q-pa-md q-color-picker__tune-tab',
|
||||
name: 'tune'
|
||||
}, getTuneTab),
|
||||
|
||||
h(QTabPanel, {
|
||||
class: 'q-color-picker__palette-tab',
|
||||
name: 'palette'
|
||||
}, getPaletteTab)
|
||||
])
|
||||
}
|
||||
|
||||
function setView (val) {
|
||||
view.value = val
|
||||
}
|
||||
|
||||
function getFooter () {
|
||||
return h('div', {
|
||||
class: 'q-color-picker__footer relative-position overflow-hidden'
|
||||
}, [
|
||||
h(QTabs, {
|
||||
class: 'absolute-full',
|
||||
modelValue: view.value,
|
||||
dense: true,
|
||||
align: 'justify',
|
||||
'onUpdate:modelValue': setView
|
||||
}, () => [
|
||||
h(QTab, {
|
||||
icon: $q.iconSet.colorPicker.spectrum,
|
||||
name: 'spectrum',
|
||||
ripple: false
|
||||
}),
|
||||
|
||||
h(QTab, {
|
||||
icon: $q.iconSet.colorPicker.tune,
|
||||
name: 'tune',
|
||||
ripple: false
|
||||
}),
|
||||
|
||||
h(QTab, {
|
||||
icon: $q.iconSet.colorPicker.palette,
|
||||
name: 'palette',
|
||||
ripple: false
|
||||
})
|
||||
])
|
||||
])
|
||||
}
|
||||
|
||||
function getSpectrumTab () {
|
||||
const data = {
|
||||
ref: spectrumRef,
|
||||
class: 'q-color-picker__spectrum non-selectable relative-position cursor-pointer'
|
||||
+ (editable.value !== true ? ' readonly' : ''),
|
||||
style: spectrumStyle.value,
|
||||
...(editable.value === true
|
||||
? {
|
||||
onClick: onSpectrumClick,
|
||||
onMousedown: onActivate
|
||||
}
|
||||
: {}
|
||||
)
|
||||
}
|
||||
|
||||
const child = [
|
||||
h('div', { style: { paddingBottom: '100%' } }),
|
||||
h('div', { class: 'q-color-picker__spectrum-white absolute-full' }),
|
||||
h('div', { class: 'q-color-picker__spectrum-black absolute-full' }),
|
||||
h('div', {
|
||||
class: 'absolute',
|
||||
style: spectrumPointerStyle.value
|
||||
}, [
|
||||
model.value.hex !== void 0
|
||||
? h('div', { class: 'q-color-picker__spectrum-circle' })
|
||||
: null
|
||||
])
|
||||
]
|
||||
|
||||
const sliders = [
|
||||
h(QSlider, {
|
||||
class: 'q-color-picker__hue non-selectable',
|
||||
modelValue: model.value.h,
|
||||
min: 0,
|
||||
max: 360,
|
||||
trackSize: '8px',
|
||||
innerTrackColor: 'transparent',
|
||||
selectionColor: 'transparent',
|
||||
readonly: editable.value !== true,
|
||||
thumbPath,
|
||||
'onUpdate:modelValue': onHue,
|
||||
onChange: onHueChange
|
||||
})
|
||||
]
|
||||
|
||||
hasAlpha.value === true && sliders.push(
|
||||
h(QSlider, {
|
||||
class: 'q-color-picker__alpha non-selectable',
|
||||
modelValue: model.value.a,
|
||||
min: 0,
|
||||
max: 100,
|
||||
trackSize: '8px',
|
||||
trackColor: 'white',
|
||||
innerTrackColor: 'transparent',
|
||||
selectionColor: 'transparent',
|
||||
trackImg: alphaTrackImg,
|
||||
readonly: editable.value !== true,
|
||||
hideSelection: true,
|
||||
thumbPath,
|
||||
...getCache('alphaSlide', {
|
||||
'onUpdate:modelValue': value => onNumericChange(value, 'a', 100),
|
||||
onChange: value => onNumericChange(value, 'a', 100, void 0, true)
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
return [
|
||||
hDir('div', data, child, 'spec', editable.value, () => spectrumDirective.value),
|
||||
h('div', { class: 'q-color-picker__sliders' }, sliders)
|
||||
]
|
||||
}
|
||||
|
||||
function getTuneTab () {
|
||||
return [
|
||||
h('div', { class: 'row items-center no-wrap' }, [
|
||||
h('div', 'R'),
|
||||
h(QSlider, {
|
||||
modelValue: model.value.r,
|
||||
min: 0,
|
||||
max: 255,
|
||||
color: 'red',
|
||||
dark: isDark.value,
|
||||
readonly: editable.value !== true,
|
||||
...getCache('rSlide', {
|
||||
'onUpdate:modelValue': value => onNumericChange(value, 'r', 255),
|
||||
onChange: value => onNumericChange(value, 'r', 255, void 0, true)
|
||||
})
|
||||
}),
|
||||
h('input', {
|
||||
value: model.value.r,
|
||||
maxlength: 3,
|
||||
readonly: editable.value !== true,
|
||||
onChange: stop,
|
||||
...getCache('rIn', {
|
||||
onInput: evt => onNumericChange(evt.target.value, 'r', 255, evt),
|
||||
onBlur: evt => onNumericChange(evt.target.value, 'r', 255, evt, true)
|
||||
})
|
||||
})
|
||||
]),
|
||||
|
||||
h('div', { class: 'row items-center no-wrap' }, [
|
||||
h('div', 'G'),
|
||||
h(QSlider, {
|
||||
modelValue: model.value.g,
|
||||
min: 0,
|
||||
max: 255,
|
||||
color: 'green',
|
||||
dark: isDark.value,
|
||||
readonly: editable.value !== true,
|
||||
...getCache('gSlide', {
|
||||
'onUpdate:modelValue': value => onNumericChange(value, 'g', 255),
|
||||
onChange: value => onNumericChange(value, 'g', 255, void 0, true)
|
||||
})
|
||||
}),
|
||||
h('input', {
|
||||
value: model.value.g,
|
||||
maxlength: 3,
|
||||
readonly: editable.value !== true,
|
||||
onChange: stop,
|
||||
...getCache('gIn', {
|
||||
onInput: evt => onNumericChange(evt.target.value, 'g', 255, evt),
|
||||
onBlur: evt => onNumericChange(evt.target.value, 'g', 255, evt, true)
|
||||
})
|
||||
})
|
||||
]),
|
||||
|
||||
h('div', { class: 'row items-center no-wrap' }, [
|
||||
h('div', 'B'),
|
||||
h(QSlider, {
|
||||
modelValue: model.value.b,
|
||||
min: 0,
|
||||
max: 255,
|
||||
color: 'blue',
|
||||
readonly: editable.value !== true,
|
||||
dark: isDark.value,
|
||||
...getCache('bSlide', {
|
||||
'onUpdate:modelValue': value => onNumericChange(value, 'b', 255),
|
||||
onChange: value => onNumericChange(value, 'b', 255, void 0, true)
|
||||
})
|
||||
}),
|
||||
h('input', {
|
||||
value: model.value.b,
|
||||
maxlength: 3,
|
||||
readonly: editable.value !== true,
|
||||
onChange: stop,
|
||||
...getCache('bIn', {
|
||||
onInput: evt => onNumericChange(evt.target.value, 'b', 255, evt),
|
||||
onBlur: evt => onNumericChange(evt.target.value, 'b', 255, evt, true)
|
||||
})
|
||||
})
|
||||
]),
|
||||
|
||||
hasAlpha.value === true ? h('div', { class: 'row items-center no-wrap' }, [
|
||||
h('div', 'A'),
|
||||
h(QSlider, {
|
||||
modelValue: model.value.a,
|
||||
color: 'grey',
|
||||
readonly: editable.value !== true,
|
||||
dark: isDark.value,
|
||||
...getCache('aSlide', {
|
||||
'onUpdate:modelValue': value => onNumericChange(value, 'a', 100),
|
||||
onChange: value => onNumericChange(value, 'a', 100, void 0, true)
|
||||
})
|
||||
}),
|
||||
h('input', {
|
||||
value: model.value.a,
|
||||
maxlength: 3,
|
||||
readonly: editable.value !== true,
|
||||
onChange: stop,
|
||||
...getCache('aIn', {
|
||||
onInput: evt => onNumericChange(evt.target.value, 'a', 100, evt),
|
||||
onBlur: evt => onNumericChange(evt.target.value, 'a', 100, evt, true)
|
||||
})
|
||||
})
|
||||
]) : null
|
||||
]
|
||||
}
|
||||
|
||||
function getPaletteTab () {
|
||||
const fn = color => h('div', {
|
||||
class: 'q-color-picker__cube col-auto',
|
||||
style: { backgroundColor: color },
|
||||
...(
|
||||
editable.value === true
|
||||
? getCache('palette#' + color, {
|
||||
onClick: () => { onPalettePick(color) }
|
||||
})
|
||||
: {}
|
||||
)
|
||||
})
|
||||
|
||||
return [
|
||||
h('div', {
|
||||
class: 'row items-center q-color-picker__palette-rows'
|
||||
+ (editable.value === true ? ' q-color-picker__palette-rows--editable' : '')
|
||||
}, computedPalette.value.map(fn))
|
||||
]
|
||||
}
|
||||
|
||||
return () => {
|
||||
const child = [ getContent() ]
|
||||
|
||||
if (props.name !== void 0 && props.disable !== true) {
|
||||
injectFormInput(child, 'push')
|
||||
}
|
||||
|
||||
props.noHeader !== true && child.unshift(
|
||||
getHeader()
|
||||
)
|
||||
|
||||
props.noFooter !== true && child.push(
|
||||
getFooter()
|
||||
)
|
||||
|
||||
return h('div', {
|
||||
class: classes.value,
|
||||
...attributes.value
|
||||
}, child)
|
||||
}
|
||||
}
|
||||
})
|
||||
106
Frontend-Learner/node_modules/quasar/src/components/color/QColor.json
generated
vendored
Normal file
106
Frontend-Learner/node_modules/quasar/src/components/color/QColor.json
generated
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
{
|
||||
"mixins": [ "composables/use-form/private.use-form" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/color-picker"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"model-value": {
|
||||
"extends": "model-value",
|
||||
"type": [ "String", "null", "undefined" ],
|
||||
"examples": [ "# v-model=\"myColor\"" ]
|
||||
},
|
||||
|
||||
"default-value": {
|
||||
"type": "String",
|
||||
"desc": "The default value to show when the model doesn't have one",
|
||||
"examples": [ "'#c0c0c0'" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"default-view": {
|
||||
"type": "String",
|
||||
"desc": "The default view of the picker",
|
||||
"default": "'spectrum'",
|
||||
"values": [ "'spectrum'", "'tune'", "'palette'" ],
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"format-model": {
|
||||
"type": "String",
|
||||
"desc": "Forces a certain model format upon the model",
|
||||
"default": "'auto'",
|
||||
"values": [ "'auto'", "'hex'", "'rgb'", "'hexa'", "'rgba'" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"palette": {
|
||||
"type": "Array",
|
||||
"desc": "Use a custom palette of colors for the palette tab",
|
||||
"default": "# hard-coded palette",
|
||||
"__runtimeDefault": true,
|
||||
"examples": [ "[ '#019A9D', '#D9B801', 'rgb(23,120,0)', '#B2028A' ]" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"square": {
|
||||
"extends": "square"
|
||||
},
|
||||
|
||||
"flat": {
|
||||
"extends": "flat"
|
||||
},
|
||||
|
||||
"bordered": {
|
||||
"extends": "bordered"
|
||||
},
|
||||
|
||||
"no-header": {
|
||||
"type": "Boolean",
|
||||
"desc": "Do not render header",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"no-header-tabs": {
|
||||
"type": "Boolean",
|
||||
"desc": "Do not render header tabs (only the input)",
|
||||
"category": "content",
|
||||
"addedIn": "v2.2"
|
||||
},
|
||||
|
||||
"no-footer": {
|
||||
"type": "Boolean",
|
||||
"desc": "Do not render footer; Useful when you want a specific view ('default-view' prop) and don't want the user to be able to switch it",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"disable": {
|
||||
"extends": "disable"
|
||||
},
|
||||
|
||||
"readonly": {
|
||||
"extends": "readonly"
|
||||
},
|
||||
|
||||
"dark": {
|
||||
"extends": "dark"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"update:model-value": {
|
||||
"extends": "update:model-value",
|
||||
"params": {
|
||||
"value": {
|
||||
"type": [ "String", "null" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"change": {
|
||||
"extends": "update:model-value",
|
||||
"desc": "Emitted on lazy model value change (after user finishes selecting a color)"
|
||||
}
|
||||
}
|
||||
}
|
||||
180
Frontend-Learner/node_modules/quasar/src/components/color/QColor.sass
generated
vendored
Normal file
180
Frontend-Learner/node_modules/quasar/src/components/color/QColor.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
.q-color-picker
|
||||
overflow: hidden
|
||||
background: #fff
|
||||
max-width: 350px
|
||||
vertical-align: top
|
||||
|
||||
min-width: 180px
|
||||
|
||||
border-radius: $generic-border-radius
|
||||
box-shadow: $shadow-2
|
||||
|
||||
.q-tab
|
||||
padding: 0 !important
|
||||
|
||||
&--bordered
|
||||
border: 1px solid $separator-color
|
||||
|
||||
&__header
|
||||
|
||||
&-tabs
|
||||
height: 32px
|
||||
&-banner
|
||||
height: 36px
|
||||
|
||||
input
|
||||
line-height: 24px
|
||||
border: 0
|
||||
|
||||
.q-tab
|
||||
min-height: 32px !important
|
||||
height: 32px !important
|
||||
|
||||
&--inactive
|
||||
background: linear-gradient(to top, rgba(0,0,0,.3) 0%, rgba(0,0,0,.15) 25%, rgba(0,0,0,.1))
|
||||
|
||||
&__error-icon
|
||||
bottom: 2px
|
||||
right: 2px
|
||||
font-size: 24px
|
||||
opacity: 0
|
||||
transition: opacity .3s ease-in
|
||||
|
||||
&__header-content
|
||||
position: relative
|
||||
background: #fff
|
||||
|
||||
&--light
|
||||
color: #000
|
||||
|
||||
&--dark
|
||||
color: #fff
|
||||
.q-tab--inactive
|
||||
&:before
|
||||
content: ''
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
background: rgba(255,255,255,.2)
|
||||
|
||||
&__header-banner
|
||||
height: 36px
|
||||
&__header-bg
|
||||
background: #fff
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAH0lEQVQoU2NkYGAwZkAFZ5G5jPRRgOYEVDeB3EBjBQBOZwTVugIGyAAAAABJRU5ErkJggg==') !important
|
||||
|
||||
&__footer
|
||||
height: 36px
|
||||
|
||||
.q-tab
|
||||
min-height: 36px !important
|
||||
height: 36px !important
|
||||
|
||||
&--inactive
|
||||
background: linear-gradient(to bottom, rgba(0,0,0,.3) 0%, rgba(0,0,0,.15) 25%, rgba(0,0,0,.1))
|
||||
|
||||
/* Saturation Tab */
|
||||
|
||||
&__spectrum
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
&__spectrum-tab
|
||||
padding: 0 !important
|
||||
|
||||
&__spectrum-white
|
||||
background: linear-gradient(to right, #fff, rgba(255,255,255,0))
|
||||
|
||||
&__spectrum-black
|
||||
background: linear-gradient(to top, #000, rgba(0,0,0,0))
|
||||
|
||||
&__spectrum-circle
|
||||
width: 10px
|
||||
height: 10px
|
||||
box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,.3), 0 0 1px 2px rgba(0,0,0,.4)
|
||||
border-radius: 50%
|
||||
transform: translate(-5px, -5px)
|
||||
|
||||
&__hue .q-slider__track
|
||||
background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%) !important
|
||||
opacity: 1
|
||||
|
||||
&__alpha
|
||||
.q-slider__track-container
|
||||
padding-top: 0
|
||||
.q-slider__track:before
|
||||
content: ''
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
border-radius: inherit
|
||||
background: linear-gradient(90deg, rgba(255,255,255,0), $grey-7)
|
||||
|
||||
&__sliders
|
||||
padding: 0 16px
|
||||
|
||||
.q-slider__thumb
|
||||
color: $grey-9
|
||||
path
|
||||
stroke-width: 2px
|
||||
fill: transparent
|
||||
.q-slider--active path
|
||||
stroke-width: 3px
|
||||
|
||||
/* Tune Tab */
|
||||
|
||||
&__tune-tab
|
||||
|
||||
.q-slider
|
||||
margin-left: 18px
|
||||
margin-right: 18px
|
||||
|
||||
input
|
||||
font-size: $color-picker-tune-tab-input-font-size
|
||||
border: 1px solid $grey-4
|
||||
border-radius: $generic-border-radius
|
||||
width: 3.5em
|
||||
|
||||
/* Palette Tab */
|
||||
|
||||
&__palette-tab
|
||||
padding: 0 !important
|
||||
|
||||
&__palette-rows
|
||||
&--editable .q-color-picker__cube
|
||||
cursor: pointer
|
||||
|
||||
&__cube
|
||||
padding-bottom: 10%
|
||||
width: 10% !important
|
||||
|
||||
/* Generic */
|
||||
|
||||
input
|
||||
color: inherit
|
||||
background: transparent
|
||||
outline: 0
|
||||
text-align: center
|
||||
.q-tabs
|
||||
overflow: hidden
|
||||
.q-tab--active
|
||||
box-shadow: 0 0 14px 3px rgba(0,0,0,.2)
|
||||
.q-focus-helper
|
||||
display: none
|
||||
.q-tab__indicator
|
||||
display: none
|
||||
.q-tab-panels
|
||||
background: inherit
|
||||
|
||||
&--dark
|
||||
box-shadow: $dark-shadow-2
|
||||
|
||||
.q-color-picker__tune-tab input
|
||||
border: 1px solid rgba(#fff, .3)
|
||||
|
||||
.q-slider__thumb
|
||||
color: $grey-1
|
||||
5
Frontend-Learner/node_modules/quasar/src/components/color/index.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/components/color/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QColor from './QColor.js'
|
||||
|
||||
export {
|
||||
QColor
|
||||
}
|
||||
1494
Frontend-Learner/node_modules/quasar/src/components/date/QDate.js
generated
vendored
Normal file
1494
Frontend-Learner/node_modules/quasar/src/components/date/QDate.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
477
Frontend-Learner/node_modules/quasar/src/components/date/QDate.json
generated
vendored
Normal file
477
Frontend-Learner/node_modules/quasar/src/components/date/QDate.json
generated
vendored
Normal file
|
|
@ -0,0 +1,477 @@
|
|||
{
|
||||
"mixins": [ "components/date/use-datetime" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/vue-components/date"
|
||||
},
|
||||
|
||||
"props": {
|
||||
"model-value": {
|
||||
"extends": "model-value",
|
||||
"type": [ "String", "Array", "Object", "null", "undefined" ],
|
||||
"desc": "Date(s) of the component; Must be Array if using 'multiple' prop; Either use this property (along with a listener for 'update:model-value' event) OR use v-model directive",
|
||||
"examples": [
|
||||
"# v-model=\"myDate\"",
|
||||
"# v-model=\"[myDate1, myDate2]\"",
|
||||
"# v-model=\"[{ from: myDateFrom, to: myDateTo }]\"",
|
||||
"# v-model=\"[myDate1, { from: myDateFrom, to: myDateTo }, myDate2]\""
|
||||
]
|
||||
},
|
||||
|
||||
"title": {
|
||||
"type": "String",
|
||||
"desc": "When specified, it overrides the default header title; Makes sense when not in 'minimal' mode",
|
||||
"examples": [ "'Birthday'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"subtitle": {
|
||||
"type": "String",
|
||||
"desc": "When specified, it overrides the default header subtitle; Makes sense when not in 'minimal' mode",
|
||||
"examples": [ "'John Doe'" ],
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"default-year-month": {
|
||||
"type": "String",
|
||||
"desc": "The default year and month to display (in YYYY/MM format) when model is unfilled (undefined or null); Please ensure it is within the navigation min/max year-month (if using them)",
|
||||
"examples": [ "'1986/02'" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"mask": {
|
||||
"default": "'YYYY/MM/DD'",
|
||||
"examples": [ "'YYYY-MM-DD'", "'MMMM Do, YYYY'", "'YYYY-MM-DD HH:mm:ss'" ]
|
||||
},
|
||||
|
||||
"default-view": {
|
||||
"type": "String",
|
||||
"desc": "The view which will be displayed by default",
|
||||
"default": "'Calendar'",
|
||||
"values": [ "'Calendar'", "'Months'", "'Years'" ],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"years-in-month-view": {
|
||||
"type": "Boolean",
|
||||
"desc": "Show the years selector in months view",
|
||||
"category": "behavior"
|
||||
},
|
||||
|
||||
"events": {
|
||||
"type": [ "Array", "Function" ],
|
||||
"desc": "A list of events to highlight on the calendar; If using a function, it receives the date as a String and must return a Boolean (matches or not); If using a function then for best performance, reference it from your scope and do not define it inline",
|
||||
"params": {
|
||||
"date": {
|
||||
"type": "String",
|
||||
"desc": "The current date being processed.",
|
||||
"examples": [ "'2018/11/05'", "'2021/10/25'" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Boolean",
|
||||
"desc": "If true, the current date will be highlighted"
|
||||
},
|
||||
"examples": [
|
||||
"[ '2018/11/05', '2018/11/06', '2018/11/09', '2018/11/23' ]",
|
||||
"date => (date[ 9 ] % 3 === 0)"
|
||||
],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"event-color": {
|
||||
"type": [ "String", "Function" ],
|
||||
"desc": "Color name (from the Quasar Color Palette); If using a function, it receives the date as a String and must return a String (color for the received date); If using a function then for best performance, reference it from your scope and do not define it inline",
|
||||
"params": {
|
||||
"date": {
|
||||
"type": "String",
|
||||
"desc": "The current date being processed.",
|
||||
"examples": [ "'2018/11/05'", "'2021/10/25'" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "String",
|
||||
"desc": "Color for the current date.",
|
||||
"examples": [ "'teal'", "'orange'" ]
|
||||
},
|
||||
"examples": [
|
||||
"'teal-10'",
|
||||
"date => (date[ 9 ] % 2 === 0 ? 'teal' : 'orange')"
|
||||
],
|
||||
"category": "style"
|
||||
},
|
||||
|
||||
"options": {
|
||||
"type": [ "Array", "Function" ],
|
||||
"desc": "Optionally configure the days that are selectable; If using a function, it receives the date as a String and must return a Boolean (is date acceptable or not); If using a function then for best performance, reference it from your scope and do not define it inline; Incompatible with 'range' prop",
|
||||
"params": {
|
||||
"date": {
|
||||
"type": "String",
|
||||
"desc": "The current date being processed.",
|
||||
"examples": [ "'2018/11/05'", "'2021/10/25'" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Boolean",
|
||||
"desc": "If true, the current date will be made available for selection"
|
||||
},
|
||||
"examples": [
|
||||
"[ '2018/11/05', '2018/11/12', '2018/11/19', '2018/11/26' ]",
|
||||
"date => (date[ 9 ] % 3 === 0)",
|
||||
"date => (date >= '2018/11/03' && date <= '2018/11/15')"
|
||||
],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"navigation-min-year-month": {
|
||||
"type": "String",
|
||||
"desc": "Lock user from navigating below a specific year+month (in YYYY/MM format); This prop is not used to correct the model; You might want to also use 'default-year-month' prop",
|
||||
"examples": [ "'2020/07'" ],
|
||||
"category": "selection"
|
||||
},
|
||||
|
||||
"navigation-max-year-month": {
|
||||
"type": "String",
|
||||
"desc": "Lock user from navigating above a specific year+month (in YYYY/MM format); This prop is not used to correct the model; You might want to also use 'default-year-month' prop",
|
||||
"examples": [ "'2020/10'" ],
|
||||
"category": "selection"
|
||||
},
|
||||
|
||||
"no-unset": {
|
||||
"type": "Boolean",
|
||||
"desc": "Remove ability to unselect a date; It does not apply to selecting a range over already selected dates",
|
||||
"category": "selection"
|
||||
},
|
||||
|
||||
"first-day-of-week": {
|
||||
"type": [ "String", "Number" ],
|
||||
"desc": "Sets the day of the week that is considered the first day (0 - Sunday, 1 - Monday, ...); This day will show in the left-most column of the calendar",
|
||||
"default": "# based on configured Quasar lang language",
|
||||
"__runtimeDefault": true,
|
||||
"examples": [
|
||||
"1",
|
||||
"# first-day-of-week=\"1\"",
|
||||
"# :first-day-of-week=\"selectedFirstDayOfTheWeek\""
|
||||
],
|
||||
"category": "model"
|
||||
},
|
||||
|
||||
"today-btn": {
|
||||
"type": "Boolean",
|
||||
"desc": "Display a button that selects the current day",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"minimal": {
|
||||
"type": "Boolean",
|
||||
"desc": "Don’t display the header",
|
||||
"category": "content"
|
||||
},
|
||||
|
||||
"multiple": {
|
||||
"type": "Boolean",
|
||||
"desc": "Allow multiple selection; Model must be Array",
|
||||
"category": "model|selection"
|
||||
},
|
||||
|
||||
"range": {
|
||||
"type": "Boolean",
|
||||
"desc": "Allow range selection; Partial compatibility with 'options' prop: selected ranges might also include 'unselectable' days",
|
||||
"category": "model|selection"
|
||||
},
|
||||
|
||||
"emit-immediately": {
|
||||
"type": "Boolean",
|
||||
"desc": "Emit model when user browses month and year too; ONLY for single selection (non-multiple, non-range)",
|
||||
"category": "model"
|
||||
}
|
||||
},
|
||||
|
||||
"slots": {
|
||||
"default": {
|
||||
"desc": "This is where additional buttons can go"
|
||||
}
|
||||
},
|
||||
|
||||
"events": {
|
||||
"update:model-value": {
|
||||
"extends": "update:model-value",
|
||||
"params": {
|
||||
"value": {
|
||||
"type": [ "String", "Array", "Object", "null" ]
|
||||
},
|
||||
"reason": {
|
||||
"type": "String",
|
||||
"desc": "Reason of the user interaction (what was picked)",
|
||||
"values": [ "'add-day'", "'remove-day'", "'add-range'", "'remove-range'", "'mask'", "'locale'", "'year'", "'month'" ]
|
||||
},
|
||||
"details": {
|
||||
"type": "Object",
|
||||
"desc": "Object of properties on the new model",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The year of the date that the user has clicked/tapped on"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The month of the date that the user has clicked/tapped on"
|
||||
},
|
||||
"day": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The day of the month that the user has clicked/tapped on"
|
||||
},
|
||||
"from": {
|
||||
"type": "Object",
|
||||
"required": false,
|
||||
"desc": "Object of properties of the range starting point (only if range)",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The month"
|
||||
},
|
||||
"day": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The day of month"
|
||||
}
|
||||
}
|
||||
},
|
||||
"to": {
|
||||
"type": "Object",
|
||||
"required": false,
|
||||
"desc": "Object of properties of the range ending point (only if range)",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The month"
|
||||
},
|
||||
"day": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The day of month"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"navigation": {
|
||||
"desc": "Emitted when user navigates to a different month or year (and even when the model changes from an outside source)",
|
||||
"params": {
|
||||
"view": {
|
||||
"type": "Object",
|
||||
"desc": "Definition of the current view (year, month)",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The month"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"range-start": {
|
||||
"desc": "User has started a range selection",
|
||||
"params": {
|
||||
"from": {
|
||||
"type": "Object",
|
||||
"desc": "Definition of date from where the range begins",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The month"
|
||||
},
|
||||
"day": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The day of month"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"range-end": {
|
||||
"desc": "User has ended a range selection",
|
||||
"params": {
|
||||
"range": {
|
||||
"type": "Object",
|
||||
"desc": "Definition of the range",
|
||||
"definition": {
|
||||
"from": {
|
||||
"type": "Object",
|
||||
"required": true,
|
||||
"desc": "Definition of date from where the range begins",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The month"
|
||||
},
|
||||
"day": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The day of month"
|
||||
}
|
||||
}
|
||||
},
|
||||
"to": {
|
||||
"type": "Object",
|
||||
"required": true,
|
||||
"desc": "Definition of date to where the range ends",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The month"
|
||||
},
|
||||
"day": {
|
||||
"type": "Number",
|
||||
"required": true,
|
||||
"desc": "The day of month"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"setToday": {
|
||||
"desc": "Change model to today",
|
||||
"params": null,
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"setView": {
|
||||
"desc": "Change current view",
|
||||
"params": {
|
||||
"view": {
|
||||
"type": "String",
|
||||
"required": true,
|
||||
"desc": "QDate view name",
|
||||
"values": [ "'Calendar'", "'Months'", "'Years'" ]
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"offsetCalendar": {
|
||||
"desc": "Increment or decrement calendar view's month or year",
|
||||
"params": {
|
||||
"type": {
|
||||
"type": "String",
|
||||
"required": true,
|
||||
"desc": "What to increment/decrement",
|
||||
"values": [ "'month'", "'year'" ]
|
||||
},
|
||||
"descending": {
|
||||
"type": "Boolean",
|
||||
"desc": "Decrement?"
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"setCalendarTo": {
|
||||
"desc": "Change current year and month of the Calendar view; It gets corrected if using navigation-min/max-year-month and sets the current view to Calendar",
|
||||
"params": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"desc": "The month"
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"setEditingRange": {
|
||||
"desc": "Configure the current editing range",
|
||||
"params": {
|
||||
"from": {
|
||||
"type": "Object",
|
||||
"desc": "Definition of date from where the range begins",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"desc": "The month"
|
||||
},
|
||||
"day": {
|
||||
"type": "Number",
|
||||
"desc": "The day of month"
|
||||
}
|
||||
}
|
||||
},
|
||||
"to": {
|
||||
"type": "Object",
|
||||
"desc": "Definition of date to where the range ends",
|
||||
"definition": {
|
||||
"year": {
|
||||
"type": "Number",
|
||||
"desc": "The year"
|
||||
},
|
||||
"month": {
|
||||
"type": "Number",
|
||||
"desc": "The month"
|
||||
},
|
||||
"day": {
|
||||
"type": "Number",
|
||||
"desc": "The day of month"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue