<script> import { loadBaseStyle } from 'primevue/base'; import { useStyle } from 'primevue/usestyle'; import { ObjectUtils } from 'primevue/utils'; import { mergeProps } from 'vue'; const inlineStyles = {}; const buttonStyles = ` .p-button { display: inline-flex; cursor: pointer; user-select: none; align-items: center; vertical-align: bottom; text-align: center; overflow: hidden; position: relative; } .p-button-label { flex: 1 1 auto; } .p-button-icon-right { order: 1; } .p-button:disabled { cursor: default; } .p-button-icon-only { justify-content: center; } .p-button-icon-only .p-button-label { visibility: hidden; width: 0; flex: 0 0 auto; } .p-button-vertical { flex-direction: column; } .p-button-icon-bottom { order: 2; } .p-buttonset .p-button { margin: 0; } .p-buttonset .p-button:not(:last-child) { border-right: 0 none; } .p-buttonset .p-button:not(:first-of-type):not(:last-of-type) { border-radius: 0; } .p-buttonset .p-button:first-of-type { border-top-right-radius: 0; border-bottom-right-radius: 0; } .p-buttonset .p-button:last-of-type { border-top-left-radius: 0; border-bottom-left-radius: 0; } .p-buttonset .p-button:focus { position: relative; z-index: 1; } `; const checkboxStyles = ` .p-checkbox { display: inline-flex; cursor: pointer; user-select: none; vertical-align: bottom; position: relative; } .p-checkbox.p-checkbox-disabled { cursor: default; } .p-checkbox-box { display: flex; justify-content: center; align-items: center; } `; const inputTextStyles = ` .p-fluid .p-inputtext { width: 100%; } /* InputGroup */ .p-inputgroup { display: flex; align-items: stretch; width: 100%; } .p-inputgroup-addon { display: flex; align-items: center; justify-content: center; } .p-inputgroup .p-float-label { display: flex; align-items: stretch; width: 100%; } .p-inputgroup .p-inputtext, .p-fluid .p-inputgroup .p-inputtext, .p-inputgroup .p-inputwrapper, .p-fluid .p-inputgroup .p-input { flex: 1 1 auto; width: 1%; } /* Floating Label */ .p-float-label { display: block; position: relative; } .p-float-label label { position: absolute; pointer-events: none; top: 50%; margin-top: -.5rem; transition-property: all; transition-timing-function: ease; line-height: 1; } .p-float-label textarea ~ label { top: 1rem; } .p-float-label input:focus ~ label, .p-float-label input.p-filled ~ label, .p-float-label textarea:focus ~ label, .p-float-label textarea.p-filled ~ label, .p-float-label .p-inputwrapper-focus ~ label, .p-float-label .p-inputwrapper-filled ~ label { top: -.75rem; font-size: 12px; } .p-float-label .input:-webkit-autofill ~ label { top: -20px; font-size: 12px; } .p-float-label .p-placeholder, .p-float-label input::placeholder, .p-float-label .p-inputtext::placeholder { opacity: 0; transition-property: all; transition-timing-function: ease; } .p-float-label .p-focus .p-placeholder, .p-float-label input:focus::placeholder, .p-float-label .p-inputtext:focus::placeholder { opacity: 1; transition-property: all; transition-timing-function: ease; } .p-input-icon-left, .p-input-icon-right { position: relative; display: inline-block; } .p-input-icon-left > i, .p-input-icon-left > svg, .p-input-icon-right > i, .p-input-icon-right > svg { position: absolute; top: 50%; margin-top: -.5rem; } .p-fluid .p-input-icon-left, .p-fluid .p-input-icon-right { display: block; width: 100%; } `; const radioButtonStyles = ` .p-radiobutton { position: relative; display: inline-flex; cursor: pointer; user-select: none; vertical-align: bottom; } .p-radiobutton.p-radiobutton-disabled { cursor: default; } .p-radiobutton-box { display: flex; justify-content: center; align-items: center; } .p-radiobutton-icon { -webkit-backface-visibility: hidden; backface-visibility: hidden; transform: translateZ(0) scale(.1); border-radius: 50%; visibility: hidden; } .p-radiobutton-box.p-highlight .p-radiobutton-icon { transform: translateZ(0) scale(1.0, 1.0); visibility: visible; } `; const styles = ` .p-component, .p-component * { box-sizing: border-box; } .p-hidden-space { visibility: hidden; } .p-reset { margin: 0; padding: 0; border: 0; outline: 0; text-decoration: none; font-size: 100%; list-style: none; } .p-disabled, .p-disabled * { cursor: default !important; pointer-events: none; user-select: none; } .p-component-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; } .p-unselectable-text { user-select: none; } .p-sr-only { border: 0; clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; word-wrap: normal !important; } .p-link { text-align: left; background-color: transparent; margin: 0; padding: 0; border: none; cursor: pointer; user-select: none; } .p-link:disabled { cursor: default; } /* Non vue overlay animations */ .p-connected-overlay { opacity: 0; transform: scaleY(0.8); transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1); } .p-connected-overlay-visible { opacity: 1; transform: scaleY(1); } .p-connected-overlay-hidden { opacity: 0; transform: scaleY(1); transition: opacity .1s linear; } /* Vue based overlay animations */ .p-connected-overlay-enter-from { opacity: 0; transform: scaleY(0.8); } .p-connected-overlay-leave-to { opacity: 0; } .p-connected-overlay-enter-active { transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1); } .p-connected-overlay-leave-active { transition: opacity .1s linear; } /* Toggleable Content */ .p-toggleable-content-enter-from, .p-toggleable-content-leave-to { max-height: 0; } .p-toggleable-content-enter-to, .p-toggleable-content-leave-from { max-height: 1000px; } .p-toggleable-content-leave-active { overflow: hidden; transition: max-height 0.45s cubic-bezier(0, 1, 0, 1); } .p-toggleable-content-enter-active { overflow: hidden; transition: max-height 1s ease-in-out; } ${buttonStyles} ${checkboxStyles} ${inputTextStyles} ${radioButtonStyles} `; const { load: loadStyle } = useStyle(styles, { name: 'common', manual: true }); export default { name: 'BaseComponent', props: { pt: { type: Object, default: undefined }, unstyled: { type: Boolean, default: undefined } }, inject: { $parentInstance: { default: undefined } }, watch: { isUnstyled: { immediate: true, handler(newValue) { if (!newValue) { loadStyle(); this.$options.css && this.$css.loadStyle(); } } } }, beforeCreate() { this.pt?.hooks?.['onBeforeCreate']?.(); this.$primevue?.config?.pt?.[this.$.type.name]?.hooks?.['onBeforeCreate']?.(); }, created() { this._hook('onCreated'); }, beforeMount() { loadBaseStyle(); this._hook('onBeforeMount'); }, mounted() { this._hook('onMounted'); }, beforeUpdate() { this._hook('onBeforeUpdate'); }, updated() { this._hook('onUpdated'); }, beforeUnmount() { this._hook('onBeforeUnmount'); }, unmounted() { this._hook('onUnmounted'); }, methods: { _hook(hookName) { const selfHook = this._getOptionValue(this.pt, `hooks.${hookName}`); const globalHook = this._getOptionValue(this.globalPT, `hooks.${hookName}`); selfHook?.(); globalHook?.(); }, _getHostInstance(instance) { return instance ? (this.$options.hostName ? (instance.$.type.name === this.$options.hostName ? instance : this._getHostInstance(instance.$parentInstance)) : instance.$parentInstance) : undefined; }, _getOptionValue(options, key = '', params = {}) { const fKeys = ObjectUtils.toFlatCase(key).split('.'); const fKey = fKeys.shift(); return fKey ? ObjectUtils.isObject(options) ? this._getOptionValue(ObjectUtils.getItemValue(options[Object.keys(options).find((k) => ObjectUtils.toFlatCase(k) === fKey) || ''], params), fKeys.join('.'), params) : undefined : ObjectUtils.getItemValue(options, params); }, _getPTValue(obj = {}, key = '', params = {}, searchInDefaultPT = true) { const getValue = (...args) => { const value = this._getOptionValue(...args); return ObjectUtils.isString(value) || ObjectUtils.isArray(value) ? { class: value } : value; }; const datasetPrefix = 'data-pc-'; const self = getValue(obj, key, params); const globalPT = searchInDefaultPT ? (/./g.test(key) && !!params[key.split('.')[0]] ? getValue(this.globalPT, key, params) : getValue(this.defaultPT, key, params)) : undefined; const merged = mergeProps(self, globalPT, { ...(key === 'root' && { [`${datasetPrefix}name`]: ObjectUtils.toFlatCase(this.$.type.name) }), [`${datasetPrefix}section`]: ObjectUtils.toFlatCase(key) }); return merged; /* * @todo: The 'class' option in self can always be more powerful to style the component easily. * * return self && self['class'] ? { ...merged, ...{ class: self['class'] } } : merged; */ }, ptm(key = '', params = {}) { return this._getPTValue(this.pt, key, { instance: this, props: this.$props, state: this.$data, ...params }); }, ptmo(obj = {}, key = '', params = {}) { return this._getPTValue(obj, key, { instance: this, ...params }, false); }, cx(key = '', params = {}) { return !this.isUnstyled ? this._getOptionValue(this.$css.classes, key, { instance: this, props: this.$props, state: this.$data, parentInstance: this.$parentInstance, ...params }) : undefined; }, sx(key = '', when = true, params = {}) { if (when) { const self = this._getOptionValue(this.$css.inlineStyles, key, { instance: this, props: this.$props, state: this.$data, parentInstance: this.$parentInstance, ...params }); const base = this._getOptionValue(inlineStyles, key, { instance: this, props: this.$props, state: this.$data, parentInstance: this.$parentInstance, ...params }); return [base, self]; } return undefined; } }, computed: { globalPT() { return ObjectUtils.getItemValue(this.$primevue.config.pt, { instance: this }); }, defaultPT() { return this._getOptionValue(this.$primevue.config.pt, this.$options.hostName || this.$.type.name, { instance: this }) || this.globalPT; }, isUnstyled() { return this.unstyled !== undefined ? this.unstyled : this.$primevue.config.unstyled; }, $css() { return { classes: undefined, inlineStyles: undefined, loadStyle: () => {}, ...(this._getHostInstance(this) || {}).$css, ...this.$options.css }; } } }; </script>