diff --git a/package.json b/package.json index baa0419..87b6123 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,13 @@ }, "devDependencies": { "@rollup/plugin-inject": "^5.0.5", - "autoprefixer": "^10.4.19", - "axios": "^1.6.4", + "autoprefixer": "^10.4.20", "laravel-vite-plugin": "^1.0", - "postcss": "^8.4.39", + "postcss": "^8.4.45", "prettier": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.6", "sass": "^1.77.6", - "tailwindcss": "^3.4.4", + "tailwindcss": "^3.4.11", "vite": "^5.0" }, "dependencies": { @@ -24,6 +23,11 @@ "notie": "^4.3.1", "sweetalert2": "^11.12.4", "toastr": "^2.1.4", - "tom-select": "^2.3.1" + "tom-select": "^2.3.1", + "apexcharts": "^3.53.0", + "axios": "^1.7.7", + "clipboard": "^2.0.11", + "esri-leaflet": "^3.0.12", + "esri-leaflet-geocoder": "^3.1.4" } } diff --git a/resources/metronic/app/datatables/allowed-ip-addresses.ts b/resources/metronic/app/datatables/allowed-ip-addresses.ts new file mode 100644 index 0000000..8d82d02 --- /dev/null +++ b/resources/metronic/app/datatables/allowed-ip-addresses.ts @@ -0,0 +1,147 @@ +import { + KTDataTable, + KTDataTableConfigInterface, + KTDataTableDataInterface, + KTDataTableInterface, +} from '../../core/components/datatable'; + +const apiUrl: string = /^(localhost|127.0.0.1)$/.test(window.location.hostname) + ? 'http://127.0.0.1:8001/metronic-tailwind-html/demo1/account/security/allowed-ip-addresses/_data.html' + : 'https://keenthemes.com/metronic/tailwind/demo1/account/security/allowed-ip-addresses/_data.html'; +const element: HTMLElement = document.querySelector('#ip_addresses_table') as HTMLElement; + + +interface IPAddressData extends KTDataTableDataInterface { + id: number; + status: string; + ipAddress: string; + lastSession: string; + label: string; + method: string; +} + +// Example usage of the plugin with server-side API, pagination, and sorting +const dataTableOptions: KTDataTableConfigInterface = { + // Initialization options for the DataTable + apiEndpoint: apiUrl, + + // mapResponse: (responseData): KTDatatableResponseDataInterface => { + // // Custom transformation logic for custom API + // return { + // data: responseData.data, // Assuming the response has an 'items' array + // totalCount: responseData.totalCount // Assuming the response has a 'total' field + // }; + // }, + + // mapRequest: (query: URLSearchParams): URLSearchParams => { + // // Custom query mapping logic + // query.set('test', 'test'); + // return query; + // }, + + // pageSizes: [5, 10, 20, 30, 50], + + pageSize: 10, + // stateSave: false, + stateNamespace: 'allowed-ip-addresses', + columns: { + select: { + render: ( + item: keyof KTDataTableDataInterface, + data: IPAddressData, + context: KTDataTableInterface + ): string => { + const checkbox = document.createElement('input'); + checkbox.className = 'checkbox checkbox-sm'; + checkbox.type = 'checkbox'; + checkbox.value = data.id.toString(); + checkbox.setAttribute('data-datatable-row-check', 'true'); + return checkbox.outerHTML.trim(); + }, + }, + status: { + title: 'Status', + render: (item: string): string => { + return ``; + }, + createdCell(cell) { + cell.classList.add('text-center'); + }, + }, + ipAddress: { + title: 'IP Address', + }, + lastSession: { + title: 'Last Session', + }, + label: { + title: 'Label', + }, + method: { + title: 'Method', + }, + edit: { + render: ( + item: string, + data: IPAddressData + ): string => { + const button = document.createElement('button'); + button.className = 'btn btn-sm btn-icon btn-clear btn-light'; + button.innerHTML = ''; + return button.outerHTML.trim(); + }, + createdCell: (cell, cellData, rowData) => { + cell.querySelector('.btn').addEventListener('click', () => { + alert(`Clicked on edit button for row ${rowData.label}`); + }); + }, + }, + delete: { + render: ( + item: string, + data: IPAddressData + ): string => { + const button = document.createElement('button'); + button.className = 'btn btn-sm btn-icon btn-clear btn-light'; + button.innerHTML = ''; + return button.outerHTML.trim(); + }, + createdCell: (cell, cellData, rowData) => { + cell.querySelector('.btn').addEventListener('click', () => { + alert(`Clicked on delete button for row ${rowData.label}`); + }); + }, + }, + }, +}; + +const dataTable = new KTDataTable(element, dataTableOptions); + +document.querySelector('#select_ip_btn').addEventListener('click', () => { + const selected = dataTable.getChecked(); + if (selected.length) { + alert(`Selected rows: ${selected}`); + } else { + alert('No rows selected'); + } +}) + +// Cache elements with the data-datatable-search attribute +const searchElements = document.querySelectorAll('[data-datatable-search]'); + +searchElements.forEach((element) => { + // Get the ID of the datatable to be searched + const tableId = element.getAttribute('data-datatable-search'); + // Find the corresponding datatable element + const datatable = document.querySelector(tableId); + + if (datatable) { + // Retrieve the datatable instance once + const dataTableInstance = (datatable as any).instance; + + // Add the event listener for the keyup event + element.addEventListener('keyup', () => { + dataTableInstance.search(element.value); + }); + } +}); diff --git a/resources/metronic/app/datatables/current-sessions.js b/resources/metronic/app/datatables/current-sessions.js new file mode 100644 index 0000000..d07fd6a --- /dev/null +++ b/resources/metronic/app/datatables/current-sessions.js @@ -0,0 +1,192 @@ +class DataTableManager { + constructor(tableElement, apiUrl) { + this.tableElement = tableElement; + this.apiUrl = apiUrl; + this.dataTableOptions = this.createDataTableOptions(); + this.dataTable = new KTDataTable(tableElement, this.dataTableOptions); + this.filterMap = this.createFilterMap(); + } + + static isLocalhost() { + return /^(localhost|127.0.0.1)$/.test(window.location.hostname); + } + + /** + * Creates the options for the DataTable. + * + * @return {Object} The options for the DataTable. + */ + createDataTableOptions() { + return { + apiEndpoint: this.apiUrl, + pageSize: 10, + columns: { + select: { + render: (item, data, context) => { + const checkbox = document.createElement('input'); + checkbox.className = 'checkbox checkbox-sm'; + checkbox.type = 'checkbox'; + checkbox.value = data.id.toString(); + checkbox.setAttribute('data-datatable-row-check', 'true'); + return checkbox.outerHTML.trim(); + }, + }, + user: { + title: 'Person', + render: (item) => { + const prefix = DataTableManager.isLocalhost() ? 'metronic-tailwind-html' : 'metronic/tailwind'; + return ` + + `; + }, + }, + browser: { + title: 'Browser', + render: (item) => { + return ` +
+ + ${item.name} +
+ `; + }, + }, + ipAddress: { + title: 'IP Address', + }, + location: { + title: 'Location', + render: (item) => { + const prefix = DataTableManager.isLocalhost() ? 'metronic-tailwind-html' : 'metronic/tailwind'; + return ` +
+ flag + ${item.name} +
+ `; + }, + }, + action: { + title: '', + render: (item) => { + return ` + + `; + }, + createdCell: (cell, cellData, rowData) => { + cell.querySelector('.btn').addEventListener('click', () => { + alert(`Clicked on action button for row ${rowData.user.name}`); + }); + }, + }, + }, + }; + } + + /** + * Creates a map of filter elements based on the data-datatable-filter-column attribute. + * + * @return {Map} A map of filter elements, where the key is the value of the data-datatable-filter-column attribute and the value is the corresponding HTMLSelectElement. + */ + createFilterMap() { + const filterElements = document.querySelectorAll( + 'select[data-datatable-filter-column]' + ); + return new Map( + Array.from(filterElements).map((el) => [ + el.getAttribute('data-datatable-filter-column'), + el, + ]) + ); + } + + /** + * Initialize the filters based on the state and map the filter elements to their corresponding datatable columns. + */ + initializeFilters() { + this.dataTable.getState().filters.forEach(({ column, value }) => { + if (this.filterMap.has(column)) { + const filterEl = this.filterMap.get(column); + if (filterEl !== null) { + filterEl.value = value || ''; + } + } + }); + + this.filterMap.forEach((el, column) => { + el.addEventListener('change', () => { + this.dataTable + .setFilter({ + column, + type: 'text', + value: el.value || '', + }) + .redraw(); + }); + }); + } + + /** + * A debounced function that delays invoking the input function until after wait milliseconds have elapsed since the last time the debounced function is invoked. + * + * @param {Function} func - The function to debounce. + * @param {number} wait - The number of milliseconds to delay. + * @return {Function} The debounced function. + */ + debounce(func, wait) { + let timeout; + return function (...args) { + const context = this; + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(context, args), wait); + }; + } + + /** + * Initializes the search functionality for the current table. + * It sets up a debounced search event listener on the search element + * to perform a search on the datatable whenever the user types in the search input. + * + * @return {void} + */ + initSearch() { + const searchElement = document.querySelector('[data-datatable-search="true"]'); + if (this.dataTable && searchElement) { + const debouncedSearch = this.debounce(() => { + this.dataTable.search(searchElement.value); + }, 300); + searchElement.addEventListener('keyup', debouncedSearch); + } + } + + /** + * Creates a new instance of DataTableManager with the specified tableElement and apiUrl. + * Initializes filters and search functionality for the instance. + * + * @param {void} + * @return {void} + */ + static createInstance() { + const apiUrl = DataTableManager.isLocalhost() + ? 'http://127.0.0.1:8001/metronic-tailwind-html/demo1/account/security/current-sessions/_data.html' + : 'https://keenthemes.com/metronic/tailwind/demo1/account/security/current-sessions/_data.html'; + const tableElement = document.querySelector('#current_sessions_table'); + + const dataTableManager = new DataTableManager(tableElement, apiUrl); + dataTableManager.initializeFilters(); + dataTableManager.initSearch(); + } +} + +KTDom.ready(() => { + DataTableManager.createInstance(); +}); diff --git a/resources/metronic/app/layouts/base.js b/resources/metronic/app/layouts/base.js index 4dbab0c..5928400 100644 --- a/resources/metronic/app/layouts/base.js +++ b/resources/metronic/app/layouts/base.js @@ -4,10 +4,10 @@ class KTLayout { } static _handleMegaMenu() { - const megamenuEl = document.querySelector('#megamenu'); - if (!megamenuEl) return; + const megaMenuEl = document.querySelector('#mega_menu'); + if (!megaMenuEl) return; - const menu = KTMenu.getInstance(megamenuEl); + const menu = KTMenu.getInstance(megaMenuEl); menu.disable(); setTimeout(() => { diff --git a/resources/metronic/app/widgets/general.js b/resources/metronic/app/widgets/general.js new file mode 100644 index 0000000..095998e --- /dev/null +++ b/resources/metronic/app/widgets/general.js @@ -0,0 +1,645 @@ +class KTGeneralWidgets { + static initCompanyProfileMap() { + const element = 'company_profile_map'; + + if (!KTDom.getElement(`#${element}`)) return; + + // Check if Leaflet is included + if (!L) { + return; + } + + // Define Map Location + const leaflet = L.map(element, { + center: [40.725, -73.985], + zoom: 30 + }); + + // Init Leaflet Map. For more info check the plugin's documentation: https://leafletjs.com/ + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© OpenStreetMap contributors' + }).addTo(leaflet); + + // Set Geocoding + let geocodeService; + if (typeof L.esri.Geocoding === 'undefined') { + geocodeService = L.esri.geocodeService(); + } else { + geocodeService = L.esri.Geocoding.geocodeService(); + } + + // Define Marker Layer + const markerLayer = L.layerGroup().addTo(leaflet); + + // Set Custom SVG icon marker + const leafletIcon = L.divIcon({ + html: ``, + bgPos: [10, 10], + iconAnchor: [20, 37], + popupAnchor: [0, -37], + className: 'leaflet-marker' + }); + + // Show current address + L.marker([40.724716, -73.984789], { icon: leafletIcon }).addTo(markerLayer).bindPopup('430 E 6th St, New York, 10009.', { closeButton: false }).openPopup(); + + // Map onClick Action + leaflet.on('click', function (e) { + geocodeService.reverse().latlng(e.latlng).run(function (error, result) { + if (error) { + return; + } + markerLayer.clearLayers(); + const selectedlocation = result.address.Match_addr; + L.marker(result.latlng, { icon: leafletIcon }).addTo(markerLayer).bindPopup(result.address.Match_addr, { closeButton: false }).openPopup(); + }); + }); + } + + static initContributionChart() { + const data = [44, 55, 41, 17, 15]; + const labels = ['ERP', 'HRM', 'DMS', 'CRM', 'DAM']; + const colors = ['var(--tw-primary)', 'var(--tw-brand)', 'var(--tw-success)', 'var(--tw-info)', 'var(--tw-warning)']; + + const options = { + series: data, + labels: labels, + colors: colors, + fill: { + colors: colors, + }, + chart: { + type: 'donut', + }, + stroke: { + show: true, + width: 2, // Set the width of the border + colors: 'var(--tw-light)' // Set the color of the border + }, + dataLabels: { + enabled: false, + }, + plotOptions: { + pie: { + expandOnClick: false, + } + }, + legend: { + offsetY: -10, + offsetX: -10, + fontSize: '13px', // Set the font size + fontWeight: '500', // Set the font weight + itemMargin: { + vertical: 1 // Reduce the vertical margin between legend items + }, + labels: { + colors: 'var(--tw-gray-700)', // Set the font color for the legend text + useSeriesColors: false // Optional: Set to true to use series colors for legend text + }, + markers: { + width: 8, + height: 8 + } + }, + responsive: [{ + breakpoint: 480, + options: { + chart: { + width: 200 + }, + legend: { + position: 'bottom' + } + } + }] + }; + + const element = document.querySelector('#contributions_chart'); + if (!element) return; + + const chart = new ApexCharts(element, options); + chart.render(); + } + + static initMediaUploadsChart() { + const data = [85, 65, 50, 70, 40, 45, 100, 55, 85, 60, 70, 90]; + const categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + + const options = { + series: [{ + name: 'series1', + data: data + }], + chart: { + height: 250, + type: 'area', + toolbar: { + show: false + } + }, + dataLabels: { + enabled: false + }, + legend: { + show: false + }, + stroke: { + curve: 'smooth', + show: true, + width: 3, + colors: ['var(--tw-primary)'] + }, + xaxis: { + categories: categories, + axisBorder: { + show: false, + }, + maxTicks: 12, + axisTicks: { + show: false + }, + labels: { + style: { + colors: 'var(--tw-gray-500)', + fontSize: '12px' + } + }, + crosshairs: { + position: 'front', + stroke: { + color: 'var(--tw-primary)', + width: 1, + dashArray: 3 + } + }, + tooltip: { + enabled: false, + formatter: undefined, + offsetY: 0, + style: { + fontSize: '12px' + } + } + }, + yaxis: { + min: 0, + max: 100, + tickAmount: 5, // This will create 5 ticks: 0, 20, 40, 60, 80, 100 + axisTicks: { + show: false + }, + labels: { + style: { + colors: 'var(--tw-gray-500)', + fontSize: '12px' + }, + formatter: (value) => { + return `$${value}K`; + } + } + }, + tooltip: { + enabled: true, + custom({series, seriesIndex, dataPointIndex, w}) { + const number = parseInt(series[seriesIndex][dataPointIndex]) * 1000; + const month = w.globals.seriesX[seriesIndex][dataPointIndex]; + const monthName = categories[month]; + + const formatter = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + }); + + const formattedNumber = formatter.format(number); + + return ( + ` +
+
${monthName}, 2024 Sales
+
+
${formattedNumber}
+ +24% +
+
+ ` + ); + } + }, + markers: { + size: 0, + colors: 'var(--tw-primary-light)', + strokeColors: 'var(--tw-primary)', + strokeWidth: 4, + strokeOpacity: 1, + strokeDashArray: 0, + fillOpacity: 1, + discrete: [], + shape: "circle", + radius: 2, + offsetX: 0, + offsetY: 0, + onClick: undefined, + onDblClick: undefined, + showNullDataPoints: true, + hover: { + size: 8, + sizeOffset: 0 + } + }, + fill: { + gradient: { + enabled: true, + opacityFrom: 0.25, + opacityTo: 0 + } + }, + grid: { + borderColor: 'var(--tw-gray-200)', + strokeDashArray: 5, + clipMarkers: false, + yaxis: { + lines: { + show: true + } + }, + xaxis: { + lines: { + show: false + } + }, + }, + }; + + const element = document.querySelector('#media_uploads_chart'); + if (!element) return; + + const chart = new ApexCharts(element, options); + chart.render(); + } + + static initEarningsChart() { + const data = [75, 25, 45, 15, 85, 35, 70, 25, 35, 15, 45, 30]; + const categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + + const options = { + series: [{ + name: 'series1', + data: data + }], + chart: { + height: 250, + type: 'area', + toolbar: { + show: false + } + }, + dataLabels: { + enabled: false + }, + legend: { + show: false + }, + stroke: { + curve: 'smooth', + show: true, + width: 3, + colors: ['var(--tw-primary)'] + }, + xaxis: { + categories: categories, + axisBorder: { + show: false, + }, + maxTicks: 12, + axisTicks: { + show: false + }, + labels: { + style: { + colors: 'var(--tw-gray-500)', + fontSize: '12px' + } + }, + crosshairs: { + position: 'front', + stroke: { + color: 'var(--tw-primary)', + width: 1, + dashArray: 3 + } + }, + tooltip: { + enabled: false, + formatter: undefined, + offsetY: 0, + style: { + fontSize: '12px' + } + } + }, + yaxis: { + min: 0, + max: 100, + tickAmount: 5, // This will create 5 ticks: 0, 20, 40, 60, 80, 100 + axisTicks: { + show: false + }, + labels: { + style: { + colors: 'var(--tw-gray-500)', + fontSize: '12px' + }, + formatter: (value) => { + return `$${value}K`; + } + } + }, + tooltip: { + enabled: true, + custom({series, seriesIndex, dataPointIndex, w}) { + const number = parseInt(series[seriesIndex][dataPointIndex]) * 1000; + const month = w.globals.seriesX[seriesIndex][dataPointIndex]; + const monthName = categories[month]; + + const formatter = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + }); + + const formattedNumber = formatter.format(number); + + return ( + ` +
+
${monthName}, 2024 Sales
+
+
${formattedNumber}
+ +24% +
+
+ ` + ); + } + }, + markers: { + size: 0, + colors: 'var(--tw-primary-light)', + strokeColors: 'var(--tw-primary)', + strokeWidth: 4, + strokeOpacity: 1, + strokeDashArray: 0, + fillOpacity: 1, + discrete: [], + shape: "circle", + radius: 2, + offsetX: 0, + offsetY: 0, + onClick: undefined, + onDblClick: undefined, + showNullDataPoints: true, + hover: { + size: 8, + sizeOffset: 0 + } + }, + fill: { + gradient: { + enabled: true, + opacityFrom: 0.25, + opacityTo: 0 + } + }, + grid: { + borderColor: 'var(--tw-gray-200)', + strokeDashArray: 5, + clipMarkers: false, + yaxis: { + lines: { + show: true + } + }, + xaxis: { + lines: { + show: false + } + }, + }, + }; + + const element = document.querySelector('#earnings_chart'); + if (!element) return; + + const chart = new ApexCharts(element, options); + chart.render(); + } + + static initMyBalanceChart(chartId, data, categories) { + const options = { + series: [{ + name: 'series1', + data: data + }], + chart: { + height: 250, + type: 'area', + toolbar: { + show: false + } + }, + dataLabels: { + enabled: false + }, + legend: { + show: false + }, + stroke: { + curve: 'smooth', + show: true, + width: 3, + colors: ['var(--tw-primary)'] + }, + xaxis: { + categories: categories, + axisBorder: { + show: false, + }, + axisTicks: { + show: false + }, + labels: { + style: { + colors: 'var(--tw-gray-600)', + fontSize: '12px' + } + }, + crosshairs: { + position: 'front', + stroke: { + color: 'var(--tw-primary)', + width: 1, + dashArray: 3 + } + }, + tooltip: { + enabled: false, + formatter: undefined, + offsetY: 0, + style: { + fontSize: '12px' + } + } + }, + yaxis: { + min: 0, + max: 100, + tickAmount: 5, + axisTicks: { + show: false + }, + labels: { + style: { + colors: 'var(--tw-gray-600)', + fontSize: '12px' + }, + formatter: (value) => { + return `$${value}K`; + } + } + }, + tooltip: { + enabled: true, + custom({series, seriesIndex, dataPointIndex, w}) { + const number = parseInt(series[seriesIndex][dataPointIndex]) * 1000; + const month = w.globals.seriesX[seriesIndex][dataPointIndex]; + const monthName = categories[month]; + + const formatter = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + }); + + const formattedNumber = formatter.format(number); + + return ( + ` +
+
${monthName}, 2024 Sales
+
+
${formattedNumber}
+ +24% +
+
+ ` + ); + } + }, + markers: { + size: 0, + colors: 'var(--tw-primary-light)', + strokeColors: 'var(--tw-primary)', + strokeWidth: 4, + strokeOpacity: 1, + strokeDashArray: 0, + fillOpacity: 1, + discrete: [], + shape: "circle", + radius: 2, + offsetX: 0, + offsetY: 0, + onClick: undefined, + onDblClick: undefined, + showNullDataPoints: true, + hover: { + size: 8, + sizeOffset: 0 + } + }, + fill: { + gradient: { + enabled: true, + opacityFrom: 0.25, + opacityTo: 0 + } + }, + grid: { + borderColor: 'var(--tw-gray-200)', + strokeDashArray: 5, + clipMarkers: false, + yaxis: { + lines: { + show: true + } + }, + xaxis: { + lines: { + show: false + } + }, + }, + }; + + const element = document.querySelector(`#${chartId}`); + if (!element) return; + + // Destroy the old chart instance if it exists + if (element.chart) { + element.chart.destroy(); + } + + const chart = new ApexCharts(element, options); + element.chart = chart; // Store the chart instance on the element + chart.render(); + } +} + +document.addEventListener('DOMContentLoaded', () => { + // Initial chart rendering + KTGeneralWidgets.initMyBalanceChart('my_balance_chart', [75, 25, 45, 15, 85, 35, 70, 25, 35], ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']); + + // Event listener for tab buttons + document.querySelectorAll('.tab-button').forEach(button => { + button.addEventListener('click', (event) => { + // Remove active class from all buttons + document.querySelectorAll('.tab-button').forEach(btn => btn.classList.remove('active')); + + // Add active class to the clicked button + event.target.classList.add('active'); + + // Determine chart data and categories based on the clicked tab + const chartId = 'my_balance_chart'; // You might need to adjust this if you have multiple charts + let data, categories; + switch (event.target.getAttribute('data-chart')) { + case 'my_balance_chart1': + data = [45, 35, 45, 35, 55, 85, 20, 25, 55]; + categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']; + break; + case 'my_balance_chart2': + data = [25, 55, 65, 45, 25, 65, 50, 40, 60]; + categories = ['Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']; + break; + case 'my_balance_chart3': + data = [80, 40, 50, 20, 50, 80, 60, 20, 30]; + categories = ['Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar']; + break; + case 'my_balance_chart4': + data = [20, 65, 20, 50, 70, 25, 40, 60, 80]; + categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']; + break; + default: + data = []; + categories = []; + } + + // Update chart with new data and categories + KTGeneralWidgets.initMyBalanceChart(chartId, data, categories); + }); + }); +}); + + +KTDom.ready(() => { + KTGeneralWidgets.initCompanyProfileMap(); + KTGeneralWidgets.initContributionChart(); + KTGeneralWidgets.initMediaUploadsChart(); + KTGeneralWidgets.initEarningsChart(); +}); \ No newline at end of file diff --git a/resources/metronic/core/components/collapse/collapse.ts b/resources/metronic/core/components/collapse/collapse.ts index 8f3e7d4..f2e0f18 100644 --- a/resources/metronic/core/components/collapse/collapse.ts +++ b/resources/metronic/core/components/collapse/collapse.ts @@ -166,7 +166,7 @@ export class KTCollapse extends KTComponent implements KTCollapseInterface { } public static createInstances(): void { - const elements = document.querySelectorAll('[data-collapse]:not([data-collapse="false"]'); + const elements = document.querySelectorAll('[data-collapse]:not([data-collapse="false"])'); elements.forEach((element) => { new KTCollapse(element as HTMLElement); diff --git a/resources/metronic/core/components/component.ts b/resources/metronic/core/components/component.ts index f30d7ab..249d88f 100644 --- a/resources/metronic/core/components/component.ts +++ b/resources/metronic/core/components/component.ts @@ -70,21 +70,21 @@ export default class KTComponent { const parts = String(value).split('|'); if (parts.length > 1) { - parts.every((part) => { - if (part.includes(':')) { - const [breakpointKey, breakpointValue] = part.split(':'); - const breakpoint = KTUtils.getBreakpoint(breakpointKey as KTBreakpointType); + for (let i = parts.length - 1; i < parts.length; i--) { + const part = parts[i]; + if (part.includes(':')) { + const [breakpointKey, breakpointValue] = part.split(':'); + const breakpoint = KTUtils.getBreakpoint(breakpointKey as KTBreakpointType); if (breakpoint <= width) { result = breakpointValue; - return false; + break; } } else { result = part; + break; } - - return true; - }); + } } else { result = value; } diff --git a/resources/metronic/core/components/datatable/types.ts b/resources/metronic/core/components/datatable/types.ts index 717e941..decef07 100644 --- a/resources/metronic/core/components/datatable/types.ts +++ b/resources/metronic/core/components/datatable/types.ts @@ -76,7 +76,7 @@ export interface KTDataTableConfigInterface { stateSave?: boolean; stateNamespace?: string; pageSizes?: number[]; - columns: { + columns?: { [key: keyof KTDataTableDataInterface | string]: { title?: string, render?: (item: KTDataTableDataInterface[keyof KTDataTableDataInterface] | string, data: KTDataTableDataInterface, context: KTDataTableInterface) => string, diff --git a/resources/metronic/core/components/dismiss/dismiss.ts b/resources/metronic/core/components/dismiss/dismiss.ts index 94ddb7f..255ae3a 100644 --- a/resources/metronic/core/components/dismiss/dismiss.ts +++ b/resources/metronic/core/components/dismiss/dismiss.ts @@ -120,7 +120,7 @@ export class KTDismiss extends KTComponent implements KTDismissInterface { } public static createInstances(): void { - const elements = document.querySelectorAll('[data-dismiss]:not([data-dismiss="false"]'); + const elements = document.querySelectorAll('[data-dismiss]:not([data-dismiss="false"])'); elements.forEach((element) => { new KTDismiss(element as HTMLElement); diff --git a/resources/metronic/core/components/menu/menu.ts b/resources/metronic/core/components/menu/menu.ts index 920c946..2cc8dc1 100644 --- a/resources/metronic/core/components/menu/menu.ts +++ b/resources/metronic/core/components/menu/menu.ts @@ -1128,7 +1128,7 @@ export class KTMenu extends KTComponent implements KTMenuInterface { public static handleClick() { KTEventHandler.on( document.body, - '.menu-item[data-menu-item-trigger] > .menu-link, .menu-item[data-menu-item-trigger] > .menu-toggle, .menu-item[data-menu-item-trigger] > .menu-label .menu-toggle, [data-menu-item-trigger]:not(.menu-item):not([data-menu-item-trigger="auto"])', + '.menu-item[data-menu-item-trigger] > .menu-link, .menu-item[data-menu-item-trigger] > .menu-label .menu-toggle, .menu-item[data-menu-item-trigger] > .menu-toggle, [data-menu-item-trigger]:not(.menu-item):not([data-menu-item-trigger="auto"])', 'click', (event: Event, target: HTMLElement) => { const menu = KTMenu.getInstance(target); @@ -1147,6 +1147,9 @@ export class KTMenu extends KTComponent implements KTMenuInterface { const menu = KTMenu.getInstance(target); if (menu !== null) { + if (target.tagName == 'a' || target.hasAttribute('href')) { + menu.dismiss(target); + } return menu.link(target, event); } } @@ -1188,12 +1191,12 @@ export class KTMenu extends KTComponent implements KTMenuInterface { } public static initHandlers(): void { + this.handleDismiss(); this.handleClickAway(); this.handleKeyboard(); this.handleMouseover(); this.handleMouseout(); this.handleClick(); - this.handleDismiss(); this.handleResize(); } diff --git a/resources/metronic/core/components/scrollable/scrollable.ts b/resources/metronic/core/components/scrollable/scrollable.ts index d1aba69..fba0bad 100644 --- a/resources/metronic/core/components/scrollable/scrollable.ts +++ b/resources/metronic/core/components/scrollable/scrollable.ts @@ -19,7 +19,7 @@ export class KTScrollable extends KTComponent implements KTScrollableInterface { save: true, dependencies: '', wrappers: '', - offset: '', + offset: '' }; protected override _config: KTScrollableConfigInterface = this._defaultConfig; protected _elementId: string | null = null; @@ -53,11 +53,12 @@ export class KTScrollable extends KTComponent implements KTScrollableInterface { protected _setupHeight(): void { if (!this._element) return; + const heightType = this._getHeightType(); const height = this._getHeight(); // Set height - if (height && height.length > 0) { + if (height && height != '0' && height.length > 0) { this._element.style.setProperty(heightType, height); } else { this._element.style.setProperty(heightType, ''); diff --git a/resources/metronic/core/components/scrollable/types.ts b/resources/metronic/core/components/scrollable/types.ts index 8d8f07f..b6b2565 100644 --- a/resources/metronic/core/components/scrollable/types.ts +++ b/resources/metronic/core/components/scrollable/types.ts @@ -2,7 +2,7 @@ export interface KTScrollableConfigInterface { save: boolean, dependencies: string, wrappers: string, - offset: string, + offset: string } export interface KTScrollableInterface { diff --git a/resources/metronic/core/components/scrollto/scrollto.ts b/resources/metronic/core/components/scrollto/scrollto.ts index 884418f..d0d2009 100644 --- a/resources/metronic/core/components/scrollto/scrollto.ts +++ b/resources/metronic/core/components/scrollto/scrollto.ts @@ -90,7 +90,7 @@ export class KTScrollto extends KTComponent implements KTScrolltoInterface { } public static createInstances(): void { - const elements = document.querySelectorAll('[data-scrollto]:not([data-scrollto="false"]'); + const elements = document.querySelectorAll('[data-scrollto]:not([data-scrollto="false"])'); elements.forEach((element) => { new KTScrollto(element as HTMLElement); diff --git a/resources/metronic/core/components/sticky/sticky.ts b/resources/metronic/core/components/sticky/sticky.ts index e32b75e..fc44b93 100644 --- a/resources/metronic/core/components/sticky/sticky.ts +++ b/resources/metronic/core/components/sticky/sticky.ts @@ -20,13 +20,14 @@ export class KTSticky extends KTComponent implements KTStickyInterface { offset: 0, reverse: false, release: '', - activate: '' + activate: '', }; protected override _config: KTStickyConfigInterface = this._defaultConfig; protected _attributeRoot: string; protected _eventTriggerState: boolean; protected _lastScrollTop: number; protected _releaseElement: HTMLElement; + protected _activateElement: HTMLElement; protected _wrapperElement: HTMLElement; constructor(element: HTMLElement, config: KTStickyConfigInterface | null = null) { @@ -38,6 +39,7 @@ export class KTSticky extends KTComponent implements KTStickyInterface { this._buildConfig(config); this._releaseElement = KTDom.getElement(this._getOption('release') as string); + this._activateElement = KTDom.getElement(this._getOption('activate') as string); this._wrapperElement = this._element.closest('[data-sticky-wrapper]'); this._attributeRoot = `data-sticky-${this._getOption('name')}`; this._eventTriggerState = true; @@ -68,21 +70,20 @@ export class KTSticky extends KTComponent implements KTStickyInterface { protected _process(): void { const reverse = this._getOption('reverse'); - const activateOffset = this._getActivateOffset(); - const releaseOffset = this._getReleaseOffset(); + const offset = this._getOffset(); - if (activateOffset < 0) { + if (offset < 0) { this._disable(); return; } const st = KTDom.getScrollTop(); - const proceed = (!this._releaseElement || releaseOffset > st); + const release = (this._releaseElement && KTDom.isPartiallyInViewport(this._releaseElement)); // Release on reverse scroll mode if (reverse === true) { // Forward scroll mode - if (st > activateOffset && proceed) { + if (st > offset && !release) { if (document.body.hasAttribute(this._attributeRoot) === false) { if (this._enable() === false) { return; @@ -101,6 +102,9 @@ export class KTSticky extends KTComponent implements KTStickyInterface { } else { if (document.body.hasAttribute(this._attributeRoot) === true) { this._disable(); + if (release) { + this._element.classList.add('release'); + } document.body.removeAttribute(this._attributeRoot); } @@ -116,7 +120,7 @@ export class KTSticky extends KTComponent implements KTStickyInterface { // Classic scroll mode } else { // Forward scroll mode - if (st > activateOffset && proceed) { + if (st > offset && !release) { if (document.body.hasAttribute(this._attributeRoot) === false) { if (this._enable() === false) { return; @@ -135,6 +139,9 @@ export class KTSticky extends KTComponent implements KTStickyInterface { } else { // back scroll mode if (document.body.hasAttribute(this._attributeRoot) === true) { this._disable(); + if (release) { + this._element.classList.add('release'); + } document.body.removeAttribute(this._attributeRoot); } @@ -148,7 +155,7 @@ export class KTSticky extends KTComponent implements KTStickyInterface { } } - protected _getActivateOffset(): number { + protected _getOffset(): number { let offset = parseInt(this._getOption('offset') as string); const activateElement = KTDom.getElement(this._getOption('activate') as string); @@ -159,16 +166,6 @@ export class KTSticky extends KTComponent implements KTStickyInterface { return offset; } - protected _getReleaseOffset(): number { - let offset = parseInt(this._getOption('offset') as string); - - if (this._releaseElement && this._releaseElement.offsetTop) { - offset = Math.abs(offset - this._releaseElement.offsetTop); - } - - return offset; - } - protected _enable(): boolean { if (!this._element) return false; @@ -235,6 +232,7 @@ export class KTSticky extends KTComponent implements KTStickyInterface { } this._element.classList.add('active'); + this._element.classList.remove('release'); return true; } diff --git a/resources/metronic/core/components/toggle-password/toggle-password.ts b/resources/metronic/core/components/toggle-password/toggle-password.ts index 5fe5d7e..4681bab 100644 --- a/resources/metronic/core/components/toggle-password/toggle-password.ts +++ b/resources/metronic/core/components/toggle-password/toggle-password.ts @@ -24,7 +24,7 @@ export class KTTogglePassword extends KTComponent implements KTTogglePasswordInt this._buildConfig(config); this._triggerElement = this._element.querySelector('[data-toggle-password-trigger]'); - this._inputElement = this._element.querySelector('input[type="password"]'); + this._inputElement = this._element.querySelector('input'); if (!this._triggerElement || !this._inputElement) { return; @@ -36,12 +36,11 @@ export class KTTogglePassword extends KTComponent implements KTTogglePasswordInt protected _handlers(): void { if (!this._element) return; - this._triggerElement.addEventListener('click', () => { + this._triggerElement.addEventListener('click', (e: Event) => { this._toggle(); }); this._inputElement.addEventListener('input', () => { - this._update(); }); } diff --git a/resources/metronic/core/components/toggle/toggle.ts b/resources/metronic/core/components/toggle/toggle.ts index 6aab462..e052954 100644 --- a/resources/metronic/core/components/toggle/toggle.ts +++ b/resources/metronic/core/components/toggle/toggle.ts @@ -131,7 +131,7 @@ export class KTToggle extends KTComponent implements KTToggleInterface { } public static createInstances(): void { - const elements = document.querySelectorAll('[data-toggle]:not([data-toggle="false"]'); + const elements = document.querySelectorAll('[data-toggle]:not([data-toggle="false"])'); elements.forEach((element) => { new KTToggle(element as HTMLElement); }); diff --git a/resources/metronic/core/components/tooltip/tooltip.ts b/resources/metronic/core/components/tooltip/tooltip.ts index 1806a50..03e31c4 100644 --- a/resources/metronic/core/components/tooltip/tooltip.ts +++ b/resources/metronic/core/components/tooltip/tooltip.ts @@ -286,7 +286,7 @@ export class KTTooltip extends KTComponent implements KTTooltipInterface { } public static createInstances(): void { - document.querySelectorAll('[data-tooltip]:not([data-tooltip="false"]').forEach((element) => { + document.querySelectorAll('[data-tooltip]:not([data-tooltip="false"])').forEach((element) => { new KTTooltip(element as HTMLElement); }); } diff --git a/resources/metronic/core/index.spa.ts b/resources/metronic/core/index.spa.ts index 1a8e452..066f6db 100644 --- a/resources/metronic/core/index.spa.ts +++ b/resources/metronic/core/index.spa.ts @@ -1,130 +1,135 @@ - /* -* Index -* @version: 1.0.0 +* Metronic * @author: Keenthemes * Copyright 2024 Keenthemes */ -import KTUtils from './helpers/utils'; import KTDom from './helpers/dom'; +import KTUtils from './helpers/utils'; import KTEventHandler from './helpers/event-handler'; -import {KTMenu} from './components/menu'; -import {KTDropdown} from './components/dropdown'; -import {KTModal} from './components/modal'; -import {KTDrawer} from './components/drawer'; -import {KTCollapse} from './components/collapse'; -import {KTDismiss} from './components/dismiss'; -import {KTTabs} from './components/tabs'; -import {KTAccordion} from './components/accordion'; -import {KTScrollspy} from './components/scrollspy'; -import {KTScrollable} from './components/scrollable'; -import {KTScrollto} from './components/scrollto'; -import {KTSticky} from './components/sticky'; -import {KTReparent} from './components/reparent'; -import {KTToggle} from './components/toggle'; -import {KTTooltip} from './components/tooltip'; -import {KTStepper} from './components/stepper'; -import {KTTheme} from './components/theme'; -import {KTImageInput} from './components/image-input'; -import {KTTogglePassword} from './components/toggle-password'; -import {KTDataTable} from './components/datatable'; +import { KTMenu } from './components/menu'; +import { KTDropdown } from './components/dropdown'; +import { KTModal } from './components/modal'; +import { KTDrawer } from './components/drawer'; +import { KTCollapse } from './components/collapse'; +import { KTDismiss } from './components/dismiss'; +import { KTTabs } from './components/tabs'; +import { KTAccordion } from './components/accordion'; +import { KTScrollspy } from './components/scrollspy'; +import { KTScrollable } from './components/scrollable'; +import { KTScrollto } from './components/scrollto'; +import { KTSticky } from './components/sticky'; +import { KTReparent } from './components/reparent'; +import { KTToggle } from './components/toggle'; +import { KTTooltip } from './components/tooltip'; +import { KTStepper } from './components/stepper'; +import { KTTheme } from './components/theme'; +import { KTImageInput } from './components/image-input'; +import { KTTogglePassword } from './components/toggle-password'; +import { KTDataTable } from './components/datatable'; -export {default as KTUtils} from './helpers/utils'; -export {default as KTDom} from './helpers/dom'; -export {default as KTEventHandler} from './helpers/event-handler'; -export {KTMenu} from './components/menu'; -export {KTDropdown} from './components/dropdown'; -export {KTModal} from './components/modal'; -export {KTDrawer} from './components/drawer'; -export {KTCollapse} from './components/collapse'; -export {KTDismiss} from './components/dismiss'; -export {KTTabs} from './components/tabs'; -export {KTAccordion} from './components/accordion'; -export {KTScrollspy} from './components/scrollspy'; -export {KTScrollable} from './components/scrollable'; -export {KTScrollto} from './components/scrollto'; -export {KTSticky} from './components/sticky'; -export {KTReparent} from './components/reparent'; -export {KTToggle} from './components/toggle' -export {KTTooltip} from './components/tooltip'; -export {KTStepper} from './components/stepper'; -export {KTTheme} from './components/theme'; -export {KTImageInput} from './components/image-input'; -export {KTTogglePassword} from './components/toggle-password'; -export {KTDataTable} from './components/datatable'; - -declare let globalThis: { - KTUtils: typeof KTUtils, - KTDom: typeof KTDom, - KTEventHandler: typeof KTEventHandler; - KTMenu: typeof KTMenu; - KTDropdown: typeof KTDropdown; - KTModal: typeof KTModal; - KTDrawer: typeof KTDrawer; - KTCollapse: typeof KTCollapse; - KTDismiss: typeof KTDismiss; - KTTabs: typeof KTTabs; - KTAccordion: typeof KTAccordion; - KTScrollspy: typeof KTScrollspy; - KTScrollable: typeof KTScrollable; - KTScrollto: typeof KTScrollto; - KTSticky: typeof KTSticky; - KTReparent: typeof KTReparent; - KTToggle: typeof KTToggle; - KTTooltip: typeof KTTooltip; - KTStepper: typeof KTStepper; - KTTheme: typeof KTTheme; - KTImageInput: typeof KTImageInput; - KTTogglePassword: typeof KTTogglePassword; -}; - -globalThis.KTUtils = KTUtils; -globalThis.KTDom = KTDom; -globalThis.KTEventHandler = KTEventHandler; -globalThis.KTMenu = KTMenu; -globalThis.KTDropdown = KTDropdown; -globalThis.KTModal = KTModal; -globalThis.KTDrawer = KTDrawer; -globalThis.KTCollapse = KTCollapse; -globalThis.KTDismiss = KTDismiss; -globalThis.KTTabs = KTTabs; -globalThis.KTAccordion = KTAccordion; -globalThis.KTScrollspy = KTScrollspy; -globalThis.KTScrollable = KTScrollable; -globalThis.KTScrollto = KTScrollto; -globalThis.KTSticky = KTSticky; -globalThis.KTReparent = KTReparent; -globalThis.KTToggle = KTToggle; -globalThis.KTTooltip = KTTooltip; -globalThis.KTStepper = KTStepper; -globalThis.KTTheme = KTTheme; -globalThis.KTImageInput = KTImageInput; -globalThis.KTTogglePassword = KTTogglePassword; +export { KTMenu } from './components/menu'; +export { KTDropdown } from './components/dropdown'; +export { KTModal } from './components/modal'; +export { KTDrawer } from './components/drawer'; +export { KTCollapse } from './components/collapse'; +export { KTDismiss } from './components/dismiss'; +export { KTTabs } from './components/tabs'; +export { KTAccordion } from './components/accordion'; +export { KTScrollspy } from './components/scrollspy'; +export { KTScrollable } from './components/scrollable'; +export { KTScrollto } from './components/scrollto'; +export { KTSticky } from './components/sticky'; +export { KTReparent } from './components/reparent'; +export { KTToggle } from './components/toggle'; +export { KTTooltip } from './components/tooltip'; +export { KTStepper } from './components/stepper'; +export { KTTheme } from './components/theme'; +export { KTImageInput } from './components/image-input'; +export { KTTogglePassword } from './components/toggle-password'; +export { KTDataTable } from './components/datatable'; const KTComponents = { - init(): void { - KTMenu.init(); - KTDropdown.init(); - KTModal.init(); - KTDrawer.init(); - KTCollapse.init(); - KTDismiss.init(); - KTTabs.init(); - KTAccordion.init(); - KTScrollspy.init(); - KTScrollable.init(); - KTScrollto.init(); - KTSticky.init(); - KTReparent.init(); - KTToggle.init(); - KTTooltip.init(); - KTStepper.init(); - KTTheme.init(); - KTImageInput.init(); - KTTogglePassword.init(); - KTDataTable.init(); - } + init(): void { + KTMenu.init(); + KTDropdown.init(); + KTModal.init(); + KTDrawer.init(); + KTCollapse.init(); + KTDismiss.init(); + KTTabs.init(); + KTAccordion.init(); + KTScrollspy.init(); + KTScrollable.init(); + KTScrollto.init(); + KTSticky.init(); + KTReparent.init(); + KTToggle.init(); + KTTooltip.init(); + KTStepper.init(); + KTTheme.init(); + KTImageInput.init(); + KTTogglePassword.init(); + KTDataTable.init(); + } }; -export default KTComponents; \ No newline at end of file +declare global { + interface Window { + KTUtils: typeof KTUtils; + KTDom: typeof KTDom; + KTEventHandler: typeof KTEventHandler; + KTMenu: typeof KTMenu; + KTDropdown: typeof KTDropdown; + KTModal: typeof KTModal; + KTDrawer: typeof KTDrawer; + KTCollapse: typeof KTCollapse; + KTDismiss: typeof KTDismiss; + KTTabs: typeof KTTabs; + KTAccordion: typeof KTAccordion; + KTScrollspy: typeof KTScrollspy; + KTScrollable: typeof KTScrollable; + KTScrollto: typeof KTScrollto; + KTSticky: typeof KTSticky; + KTReparent: typeof KTReparent; + KTToggle: typeof KTToggle; + KTTooltip: typeof KTTooltip; + KTStepper: typeof KTStepper; + KTTheme: typeof KTTheme; + KTImageInput: typeof KTImageInput; + KTTogglePassword: typeof KTTogglePassword; + KTDataTable: typeof KTDataTable; + KTComponents: typeof KTComponents; + } +} + +window.KTUtils = KTUtils; +window.KTDom = KTDom; +window.KTEventHandler = KTEventHandler; +window.KTMenu = KTMenu; +window.KTDropdown = KTDropdown; +window.KTModal = KTModal; +window.KTDrawer = KTDrawer; +window.KTCollapse = KTCollapse; +window.KTDismiss = KTDismiss; +window.KTTabs = KTTabs; +window.KTAccordion = KTAccordion; +window.KTScrollspy = KTScrollspy; +window.KTScrollable = KTScrollable; +window.KTScrollto = KTScrollto; +window.KTSticky = KTSticky; +window.KTReparent = KTReparent; +window.KTToggle = KTToggle; +window.KTTooltip = KTTooltip; +window.KTStepper = KTStepper; +window.KTTheme = KTTheme; +window.KTImageInput = KTImageInput; +window.KTTogglePassword = KTTogglePassword; +window.KTDataTable = KTDataTable; +window.KTComponents = KTComponents; + +export default KTComponents; + +KTDom.ready(() => { + KTComponents.init(); +}); diff --git a/resources/metronic/core/index.ts b/resources/metronic/core/index.ts index f4fef06..066f6db 100644 --- a/resources/metronic/core/index.ts +++ b/resources/metronic/core/index.ts @@ -1,10 +1,9 @@ - /* -* Index -* @version: 1.0.0 +* Metronic * @author: Keenthemes * Copyright 2024 Keenthemes */ + import KTDom from './helpers/dom'; import KTUtils from './helpers/utils'; import KTEventHandler from './helpers/event-handler'; @@ -51,57 +50,57 @@ export { KTTogglePassword } from './components/toggle-password'; export { KTDataTable } from './components/datatable'; const KTComponents = { - init(): void { - KTMenu.init(); - KTDropdown.init(); - KTModal.init(); - KTDrawer.init(); - KTCollapse.init(); - KTDismiss.init(); - KTTabs.init(); - KTAccordion.init(); - KTScrollspy.init(); - KTScrollable.init(); - KTScrollto.init(); - KTSticky.init(); - KTReparent.init(); - KTToggle.init(); - KTTooltip.init(); - KTStepper.init(); - KTTheme.init(); - KTImageInput.init(); - KTTogglePassword.init(); - KTDataTable.init(); - } + init(): void { + KTMenu.init(); + KTDropdown.init(); + KTModal.init(); + KTDrawer.init(); + KTCollapse.init(); + KTDismiss.init(); + KTTabs.init(); + KTAccordion.init(); + KTScrollspy.init(); + KTScrollable.init(); + KTScrollto.init(); + KTSticky.init(); + KTReparent.init(); + KTToggle.init(); + KTTooltip.init(); + KTStepper.init(); + KTTheme.init(); + KTImageInput.init(); + KTTogglePassword.init(); + KTDataTable.init(); + } }; declare global { - interface Window { - KTUtils: typeof KTUtils; - KTDom: typeof KTDom; - KTEventHandler: typeof KTEventHandler; - KTMenu: typeof KTMenu; - KTDropdown: typeof KTDropdown; - KTModal: typeof KTModal; - KTDrawer: typeof KTDrawer; - KTCollapse: typeof KTCollapse; - KTDismiss: typeof KTDismiss; - KTTabs: typeof KTTabs; - KTAccordion: typeof KTAccordion; - KTScrollspy: typeof KTScrollspy; - KTScrollable: typeof KTScrollable; - KTScrollto: typeof KTScrollto; - KTSticky: typeof KTSticky; - KTReparent: typeof KTReparent; - KTToggle: typeof KTToggle; - KTTooltip: typeof KTTooltip; - KTStepper: typeof KTStepper; - KTTheme: typeof KTTheme; - KTImageInput: typeof KTImageInput; - KTTogglePassword: typeof KTTogglePassword; - KTDataTable: typeof KTDataTable; - KTComponents: typeof KTComponents; - } + interface Window { + KTUtils: typeof KTUtils; + KTDom: typeof KTDom; + KTEventHandler: typeof KTEventHandler; + KTMenu: typeof KTMenu; + KTDropdown: typeof KTDropdown; + KTModal: typeof KTModal; + KTDrawer: typeof KTDrawer; + KTCollapse: typeof KTCollapse; + KTDismiss: typeof KTDismiss; + KTTabs: typeof KTTabs; + KTAccordion: typeof KTAccordion; + KTScrollspy: typeof KTScrollspy; + KTScrollable: typeof KTScrollable; + KTScrollto: typeof KTScrollto; + KTSticky: typeof KTSticky; + KTReparent: typeof KTReparent; + KTToggle: typeof KTToggle; + KTTooltip: typeof KTTooltip; + KTStepper: typeof KTStepper; + KTTheme: typeof KTTheme; + KTImageInput: typeof KTImageInput; + KTTogglePassword: typeof KTTogglePassword; + KTDataTable: typeof KTDataTable; + KTComponents: typeof KTComponents; + } } window.KTUtils = KTUtils; @@ -132,6 +131,5 @@ window.KTComponents = KTComponents; export default KTComponents; KTDom.ready(() => { - KTComponents.init(); + KTComponents.init(); }); - diff --git a/resources/metronic/core/plugins/components/accordion.js b/resources/metronic/core/plugins/components/accordion.js index e65d01a..95fc275 100644 --- a/resources/metronic/core/plugins/components/accordion.js +++ b/resources/metronic/core/plugins/components/accordion.js @@ -11,6 +11,7 @@ export default plugin(({addComponents}) => { 'display': 'flex', 'flex-grow': '1', 'align-items': 'center', + 'text-align': 'start', 'justify-content': 'space-between', }, '.accordion-content': { diff --git a/resources/metronic/core/plugins/components/btn.js b/resources/metronic/core/plugins/components/btn.js index 666ed8a..a569c5b 100644 --- a/resources/metronic/core/plugins/components/btn.js +++ b/resources/metronic/core/plugins/components/btn.js @@ -209,7 +209,6 @@ export default plugin(({addComponents, theme}) => { 'padding-left': '0', 'padding-right': '0', 'border-radius': '0', - 'font-weight': theme('fontWeight.semibold'), 'background-color': 'transparent', 'border-bottom': '1px dashed var(--tw-primary)', '&:hover, &:focus, &:active, &.active' : { diff --git a/resources/metronic/core/plugins/components/checkbox.js b/resources/metronic/core/plugins/components/checkbox.js index 5069685..60f47c3 100644 --- a/resources/metronic/core/plugins/components/checkbox.js +++ b/resources/metronic/core/plugins/components/checkbox.js @@ -10,6 +10,9 @@ export default plugin(({addComponents, theme}) => { 'appearance': 'none', 'box-shadow': 'none', 'background-color': 'var(--tw-light-light)', + '.dark &': { + 'background-color': 'var(--tw-coal-500)', + }, 'border-radius': theme('custom.components.checkbox.DEFAULT.borderRadius'), 'height': theme('custom.components.checkbox.DEFAULT.size'), 'width': theme('custom.components.checkbox.DEFAULT.size'), diff --git a/resources/metronic/core/plugins/components/container.js b/resources/metronic/core/plugins/components/container.js index 971b510..008e4ef 100644 --- a/resources/metronic/core/plugins/components/container.js +++ b/resources/metronic/core/plugins/components/container.js @@ -6,6 +6,7 @@ export default plugin(({addComponents, theme}) => { addComponents({ '.container-fixed': { 'flex-grow': '1', + 'width': '100%', 'padding-left': theme('custom.components.container.fixed.px.DEFAULT'), 'padding-right': theme('custom.components.container.fixed.px.DEFAULT') }, @@ -23,6 +24,7 @@ export default plugin(({addComponents, theme}) => { // Fluid addComponents({ '.container-fluid': { + 'width': '100%', 'flex-grow': '1', 'padding-left': theme('custom.components.container.fluid.px.DEFAULT'), 'padding-right': theme('custom.components.container.fluid.px.DEFAULT') diff --git a/resources/metronic/core/plugins/components/radio.js b/resources/metronic/core/plugins/components/radio.js index 69857b2..d62cb0f 100644 --- a/resources/metronic/core/plugins/components/radio.js +++ b/resources/metronic/core/plugins/components/radio.js @@ -10,6 +10,9 @@ export default plugin(({addComponents, theme}) => { 'appearance': 'none', 'box-shadow': 'none', 'background-color': 'var(--tw-light-light)', + '.dark &': { + 'background-color': 'var(--tw-coal-500)', + }, 'border-radius': '50%', 'height': theme('custom.components.radio.DEFAULT.size'), 'width': theme('custom.components.radio.DEFAULT.size'), diff --git a/resources/metronic/core/plugins/plugin.js b/resources/metronic/core/plugins/plugin.js index 4e984b3..73d8054 100644 --- a/resources/metronic/core/plugins/plugin.js +++ b/resources/metronic/core/plugins/plugin.js @@ -27,13 +27,19 @@ export default plugin(({config, addBase, addComponents, addVariant, e}) => { 'flex-grow': '1', 'line-height': '1', }, + '.menu-toggle': { + 'display': 'flex', + 'align-items': 'center', + 'flex-grow': '1', + 'line-height': '1', + }, '.menu-title': { 'display': 'flex', 'align-items': 'center', 'line-height': '1', 'flex-grow': '1', }, - '.menu-icon, .menu-toggle, .menu-bullet, .menu-badge, .menu-arrow': { + '.menu-icon, .menu-bullet, .menu-badge, .menu-arrow': { 'display': 'flex', 'align-items': 'center', 'flex-shrink': '0', @@ -85,6 +91,16 @@ export default plugin(({config, addBase, addComponents, addVariant, e}) => { modifySelectors(({className}) => { return `.menu-item.active > .menu-label .${e(`menu-item-active${separator}${className}`)}`; }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.active > .menu-toggle.${e(`menu-item-active${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.active > .menu-toggle .${e(`menu-item-active${separator}${className}`)}`; + }); } ]); @@ -113,6 +129,16 @@ export default plugin(({config, addBase, addComponents, addVariant, e}) => { modifySelectors(({className}) => { return `.menu-item.here > .menu-label .${e(`menu-item-here${separator}${className}`)}`; }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.here > .menu-toggle.${e(`menu-item-here${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.here > .menu-toggle .${e(`menu-item-here${separator}${className}`)}`; + }); } ]); @@ -141,6 +167,54 @@ export default plugin(({config, addBase, addComponents, addVariant, e}) => { modifySelectors(({className}) => { return `.menu-item.show > .menu-label .${e(`menu-item-show${separator}${className}`)}`; }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.show > .menu-toggle.${e(`menu-item-show${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.show > .menu-toggle .${e(`menu-item-show${separator}${className}`)}`; + }); + } + ]); + + addVariant('menu-item-disabled', [ + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.disabled.${e(`menu-item-disabled${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.disabled > .menu-link.${e(`menu-item-disabled${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.disabled > .menu-link .${e(`menu-item-disabled${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.disabled > .menu-label.${e(`menu-item-disabled${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.disabled > .menu-label .${e(`menu-item-disabled${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.disabled > .menu-toggle.${e(`menu-item-disabled${separator}${className}`)}`; + }); + }, + ({modifySelectors, separator}) => { + modifySelectors(({className}) => { + return `.menu-item.disabled > .menu-toggle .${e(`menu-item-disabled${separator}${className}`)}`; + }); } ]); @@ -168,7 +242,7 @@ export default plugin(({config, addBase, addComponents, addVariant, e}) => { return `.menu-link:focus .${e(`menu-link-focus${separator}${className}`)}`; }); }, - ]); + ]); // DataTable addVariant('datatable-loading', [ diff --git a/resources/metronic/css/base.css b/resources/metronic/css/base.css index 8d9bf41..31b289a 100644 --- a/resources/metronic/css/base.css +++ b/resources/metronic/css/base.css @@ -1,126 +1,126 @@ /* Variables */ .metronic { - --tw-sidebar-transition-duration: 0.3s; - --tw-sidebar-transition-timing: ease; - --tw-sidebar-width: theme('custom.layouts.metronic.sidebar.width.desktop'); - --tw-sidebar-defualt-width: theme('custom.layouts.metronic.sidebar.width.desktop'); - --tw-header-height: theme('custom.layouts.metronic.header.height.desktop'); + --tw-sidebar-transition-duration: 0.3s; + --tw-sidebar-transition-timing: ease; + --tw-sidebar-width: theme('custom.layouts.metronic.sidebar.width.desktop'); + --tw-sidebar-defualt-width: theme('custom.layouts.metronic.sidebar.width.desktop'); + --tw-header-height: theme('custom.layouts.metronic.header.height.desktop'); } @media (max-width: theme('screens.lg')) { - .metronic { - --tw-sidebar-width: theme('custom.layouts.metronic.sidebar.width.mobile'); - --tw-header-height: theme('custom.layouts.metronic.header.height.mobile'); - } + .metronic { + --tw-sidebar-width: theme('custom.layouts.metronic.sidebar.width.mobile'); + --tw-header-height: theme('custom.layouts.metronic.header.height.mobile'); + } } /* Base */ .metronic .header { - height: var(--tw-header-height); + height: var(--tw-header-height); } .metronic .sidebar { - width: var(--tw-sidebar-width); + width: var(--tw-sidebar-width); } .metronic.header-fixed .wrapper { - padding-top: var(--tw-header-height); + padding-top: var(--tw-header-height); } /* Desktop mode */ @media (min-width: theme('screens.lg')) { - .metronic .sidebar { - width: var(--tw-sidebar-width); - transition: width var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); - } + .metronic .sidebar { + width: var(--tw-sidebar-width); + transition: width var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); + } - .metronic .sidebar .sidebar-header { - height: var(--tw-header-height); - } + .metronic .sidebar .sidebar-header { + height: var(--tw-header-height); + } - .metronic .sidebar .sidebar-wrapper { - width: var(--tw-sidebar-defualt-width); - } + .metronic .sidebar .sidebar-wrapper { + width: var(--tw-sidebar-defualt-width); + } - .metronic .sidebar .sidebar-logo { - width: var(--tw-sidebar-defualt-width); - } + .metronic .sidebar .sidebar-logo { + width: var(--tw-sidebar-defualt-width); + } - .metronic .sidebar .small-logo { - display: none; - } + .metronic .sidebar .small-logo { + display: none; + } - .metronic.sidebar-fixed .wrapper { - padding-left: var(--tw-sidebar-width); - transition: padding-left var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); - } + .metronic.sidebar-fixed .wrapper { + padding-left: var(--tw-sidebar-width); + transition: padding-left var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); + } - .metronic.sidebar-fixed.header-fixed .header { - left: var(--tw-sidebar-width); - transition: left var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); - } + .metronic.sidebar-fixed.header-fixed .header { + left: var(--tw-sidebar-width); + transition: left var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); + } - .metronic.sidebar-fixed.header-fixed .wrapper { - padding-top: var(--tw-header-height); - } + .metronic.sidebar-fixed.header-fixed .wrapper { + padding-top: var(--tw-header-height); + } - .metronic.sidebar-collapse { - --tw-sidebar-width: theme('custom.layouts.metronic.sidebar.width.desktopCollapse'); - } + .metronic.sidebar-collapse { + --tw-sidebar-width: theme('custom.layouts.metronic.sidebar.width.desktopCollapse'); + } - .metronic.sidebar-collapse .sidebar { - transition: width var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); - } + .metronic.sidebar-collapse .sidebar { + transition: width var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); + } - .metronic.sidebar-collapse .sidebar.animating { - pointer-events: none; - } + .metronic.sidebar-collapse .sidebar.animating { + pointer-events: none; + } - .metronic.sidebar-collapse .sidebar:hover:not(.animating) { - width: var(--tw-sidebar-defualt-width); - transition: width var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); - } + .metronic.sidebar-collapse .sidebar:hover:not(.animating) { + width: var(--tw-sidebar-defualt-width); + transition: width var(--tw-sidebar-transition-duration) var(--tw-sidebar-transition-timing); + } - .metronic.sidebar-collapse .sidebar:not(:hover) .default-logo { - display: none; - } + .metronic.sidebar-collapse .sidebar:not(:hover) .default-logo { + display: none; + } - .metronic.sidebar-collapse .sidebar:not(:hover) .small-logo { - display: flex; - } + .metronic.sidebar-collapse .sidebar:not(:hover) .small-logo { + display: flex; + } - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-link .menu-title, - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-link .menu-arrow, - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-link .menu-badge, - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-label .menu-title, - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-label .menu-arrow, - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-label .menu-badge { - display: none; - } + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-link .menu-title, + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-link .menu-arrow, + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-link .menu-badge, + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-label .menu-title, + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-label .menu-arrow, + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-label .menu-badge { + display: none; + } - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-accordion { - display: none; - } + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-accordion { + display: none; + } - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-heading { - visibility: hidden; - position: relative; - } + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-heading { + visibility: hidden; + position: relative; + } - .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-heading::before { - content: "..."; - color: currentColor; - font-size: inherit; - position: absolute; - visibility: visible; - display: inline-block; - bottom: 50%; - left: 0; - margin-left: 0.225rem; - transform: translateX(100%); - } + .metronic.sidebar-collapse .sidebar:not(:hover) .menu > .menu-item > .menu-heading::before { + content: "..."; + color: currentColor; + font-size: inherit; + position: absolute; + visibility: visible; + display: inline-block; + bottom: 50%; + left: 0; + margin-left: 0.225rem; + transform: translateX(100%); + } - .metronic.sidebar-collapse .sidebar .sidebar-content { - overflow: hidden; - } + .metronic.sidebar-collapse .sidebar .sidebar-content { + overflow: hidden; + } }