@tak-ps/vue-tabler 4.10.1 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,13 +17,17 @@ jobs:
17
17
 
18
18
  - uses: actions/setup-node@v6
19
19
  with:
20
- node-version: 22
20
+ node-version: 24
21
+ cache: npm
22
+ registry-url: https://registry.npmjs.org
21
23
 
22
- - name: Update npm
23
- run: npm install -g npm@latest
24
+ - name: Install dependencies
25
+ run: npm ci
24
26
 
25
- - name: npm install
26
- run: npm install
27
+ - name: Verify package
28
+ run: |
29
+ npm run check
30
+ npm test
27
31
 
28
- - name: npm publish
32
+ - name: Publish package
29
33
  run: npm publish --provenance --access public
package/CHANGELOG.md CHANGED
@@ -10,6 +10,26 @@
10
10
 
11
11
  ## Version History
12
12
 
13
+ ### v4.12.0
14
+
15
+ - :rocket: Light mode support for TablerIconButton and TablerInput
16
+
17
+ ### v4.11.3
18
+
19
+ - :bug: GH Actions Updates
20
+
21
+ ### v4.11.2
22
+
23
+ - :bug: TS@6 Compatibility
24
+
25
+ ### v4.11.1
26
+
27
+ - :arrow_up: Move typescript-eslint to dev deps
28
+
29
+ ### v4.11.0
30
+
31
+ - :rocket: Improved Dropdown Style
32
+
13
33
  ### v4.10.1
14
34
 
15
35
  - :arrow_up: Update Core Deps
@@ -18,7 +18,7 @@
18
18
  <ul
19
19
  :class='menuClasses'
20
20
  :style='{
21
- "width": width
21
+ width
22
22
  }'
23
23
  :aria-labelledby='id'
24
24
  >
@@ -50,8 +50,8 @@ const props = withDefaults(defineProps<DropdownProps>(), {
50
50
  const id = ref('tabler-dropdown-' + Math.random().toString(36).substr(2, 9) + '-' + Date.now().toString(36));
51
51
 
52
52
  const dropdownClasses = computed(() => {
53
- const baseClass = 'dropdown';
54
-
53
+ const baseClass = 'dropdown tabler-dropdown';
54
+
55
55
  switch (props.position) {
56
56
  case 'top':
57
57
  case 'top-start':
@@ -67,8 +67,8 @@ const dropdownClasses = computed(() => {
67
67
  });
68
68
 
69
69
  const menuClasses = computed(() => {
70
- const baseClasses = 'dropdown-menu dropdown-menu-card';
71
-
70
+ const baseClasses = 'dropdown-menu dropdown-menu-card tabler-dropdown__menu';
71
+
72
72
  switch (props.position) {
73
73
  case 'bottom-start':
74
74
  case 'top-start':
@@ -81,3 +81,78 @@ const menuClasses = computed(() => {
81
81
  }
82
82
  });
83
83
  </script>
84
+
85
+ <style scoped>
86
+ .tabler-dropdown__menu {
87
+ --tabler-dropdown-color: rgba(255, 255, 255, 0.92);
88
+ --tabler-dropdown-bg: rgba(20, 20, 25, 0.96);
89
+ --tabler-dropdown-border-color: rgba(255, 255, 255, 0.25);
90
+ --tabler-dropdown-hover-bg: rgba(255, 255, 255, 0.1);
91
+ --tabler-dropdown-active-bg: rgba(var(--tblr-primary-rgb), 0.25);
92
+ --tabler-dropdown-active-color: var(--tblr-primary);
93
+ --tabler-dropdown-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.35);
94
+ margin-block: 0.25rem;
95
+ padding: 0.25rem 0;
96
+ overflow: hidden;
97
+ color: var(--tabler-dropdown-color);
98
+ border-color: var(--tabler-dropdown-border-color);
99
+ background: var(--tabler-dropdown-bg);
100
+ backdrop-filter: blur(8px);
101
+ box-shadow: var(--tabler-dropdown-shadow);
102
+ }
103
+
104
+ [data-bs-theme='light'] .tabler-dropdown__menu {
105
+ --tabler-dropdown-color: var(--tblr-body-color);
106
+ --tabler-dropdown-bg: rgba(255, 255, 255, 0.96);
107
+ --tabler-dropdown-border-color: rgba(var(--tblr-primary-rgb), 0.15);
108
+ --tabler-dropdown-hover-bg: rgba(var(--tblr-primary-rgb), 0.08);
109
+ --tabler-dropdown-active-bg: rgba(var(--tblr-primary-rgb), 0.16);
110
+ --tabler-dropdown-shadow: 0 0.5rem 1rem rgba(15, 23, 42, 0.08);
111
+ }
112
+
113
+ [data-bs-theme='light'] .tabler-dropdown__menu :deep(.dropdown-item),
114
+ [data-bs-theme='light'] .tabler-dropdown__menu :deep(.tabler-dropdown__item),
115
+ [data-bs-theme='light'] .tabler-dropdown__menu :deep(.text-white) {
116
+ color: var(--tblr-body-color) !important;
117
+ }
118
+
119
+ [data-bs-theme='light'] .tabler-dropdown__menu :deep(.text-white-50) {
120
+ color: var(--tblr-secondary-color) !important;
121
+ }
122
+
123
+ .tabler-dropdown__menu.dropdown-menu-arrow::before,
124
+ .tabler-dropdown__menu.dropdown-menu-arrow::after {
125
+ display: none;
126
+ }
127
+
128
+ .tabler-dropdown__menu :deep(.dropdown-item),
129
+ .tabler-dropdown__menu :deep(.tabler-dropdown__item) {
130
+ cursor: pointer;
131
+ color: inherit;
132
+ transition: background 0.1s ease, color 0.1s ease;
133
+ }
134
+
135
+ .tabler-dropdown__menu :deep(.dropdown-item:hover),
136
+ .tabler-dropdown__menu :deep(.tabler-dropdown__item:hover) {
137
+ background: var(--tabler-dropdown-hover-bg);
138
+ }
139
+
140
+ .tabler-dropdown__menu :deep(.dropdown-item.active),
141
+ .tabler-dropdown__menu :deep(.dropdown-item:active),
142
+ .tabler-dropdown__menu :deep(.tabler-dropdown__item--active) {
143
+ background: var(--tabler-dropdown-active-bg);
144
+ color: var(--tabler-dropdown-active-color);
145
+ }
146
+
147
+ .tabler-dropdown__menu :deep(.dropdown-item.active .text-white),
148
+ .tabler-dropdown__menu :deep(.dropdown-item:active .text-white),
149
+ .tabler-dropdown__menu :deep(.tabler-dropdown__item--active .text-white) {
150
+ color: var(--tabler-dropdown-active-color) !important;
151
+ }
152
+
153
+ .tabler-dropdown__menu :deep(.dropdown-item.active .text-white-50),
154
+ .tabler-dropdown__menu :deep(.dropdown-item:active .text-white-50),
155
+ .tabler-dropdown__menu :deep(.tabler-dropdown__item--active .text-white-50) {
156
+ color: rgba(var(--tblr-primary-rgb), 0.7) !important;
157
+ }
158
+ </style>
@@ -48,7 +48,19 @@ const iconButtonStyle = computed(() => {
48
48
  color: var(--tblr-gray-500);
49
49
  }
50
50
 
51
- .custom-hover:not(.disabled):hover {
52
- background-color: var(--tblr-border-color);
51
+ .custom-hover:not(.disabled) {
52
+ transition: background-color 0.15s ease, color 0.15s ease;
53
+ }
54
+
55
+ [data-bs-theme='light'] .custom-hover:not(.disabled):hover,
56
+ [data-bs-theme='light'] .custom-hover:not(.disabled):focus-visible {
57
+ background-color: var(--cloudtak-light, rgba(var(--tblr-primary-rgb), 0.08));
58
+ color: var(--tblr-body-color);
59
+ }
60
+
61
+ [data-bs-theme='dark'] .custom-hover:not(.disabled):hover,
62
+ [data-bs-theme='dark'] .custom-hover:not(.disabled):focus-visible {
63
+ background-color: var(--tblr-light);
64
+ color: var(--tblr-dark);
53
65
  }
54
66
  </style>
@@ -318,6 +318,29 @@ input:autofill {
318
318
  color calc(infinity * 1s) step-end;
319
319
  }
320
320
 
321
+ .input-group :deep(.form-control),
322
+ .position-relative > .form-control,
323
+ .input-group :deep(.input-group-text) {
324
+ border-color: var(--tblr-border-color);
325
+ }
326
+
327
+ .input-group :deep(.form-control),
328
+ .position-relative > .form-control {
329
+ color: var(--tblr-body-color);
330
+ background-color: var(--tabler-input-bg, var(--tblr-bg-forms, var(--tblr-bg-surface, var(--tblr-body-bg))));
331
+ }
332
+
333
+ .input-group :deep(.form-control)::placeholder,
334
+ .position-relative > .form-control::placeholder {
335
+ color: var(--tblr-secondary-color);
336
+ opacity: 1;
337
+ }
338
+
339
+ .input-group :deep(.input-group-text) {
340
+ color: var(--tblr-body-color);
341
+ background-color: var(--tabler-input-bg, var(--tblr-bg-forms, var(--tblr-bg-surface, var(--tblr-body-bg))));
342
+ }
343
+
321
344
  .tabler-input-with-end {
322
345
  padding-right: 3rem;
323
346
  }
@@ -357,7 +380,7 @@ input:autofill {
357
380
  }
358
381
 
359
382
  .tabler-input-end {
360
- color: var(--tblr-white);
383
+ color: var(--tblr-body-color);
361
384
  opacity: 1;
362
385
  }
363
386
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/vue-tabler",
3
3
  "type": "module",
4
- "version": "4.10.1",
4
+ "version": "4.12.0",
5
5
  "lib": "lib.ts",
6
6
  "main": "lib.ts",
7
7
  "module": "lib.ts",
@@ -27,11 +27,10 @@
27
27
  "homepage": "https://github.com/tak-ps/vue-tabler#readme",
28
28
  "dependencies": {
29
29
  "@tabler/icons-vue": "^3.0.0",
30
- "showdown": "^2.1.0",
31
- "typescript-eslint": "^8.36.0",
32
- "vue": "^3.5.12"
30
+ "showdown": "^2.1.0"
33
31
  },
34
32
  "peerDependencies": {
33
+ "vue": "^3.5.12",
35
34
  "vue-router": "^5.0.0"
36
35
  },
37
36
  "devDependencies": {
@@ -43,9 +42,11 @@
43
42
  "eslint-plugin-vue": "^10.0.0",
44
43
  "globals": "^17.0.0",
45
44
  "jsdom": "^29.0.0",
46
- "typescript": "^5.9.3",
45
+ "typescript": "^6.0.0",
46
+ "typescript-eslint": "^8.36.0",
47
47
  "vite": "^8.0.0",
48
48
  "vitest": "^4.1.0",
49
+ "vue": "^3.5.12",
49
50
  "vue-tsc": "^3.2.1"
50
51
  }
51
52
  }
@@ -0,0 +1,59 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ import { describe, expect, it } from 'vitest'
4
+ import { mount } from '@vue/test-utils'
5
+ import IconButton from '../components/IconButton.vue'
6
+ import iconButtonSource from '../components/IconButton.vue?raw'
7
+
8
+ const global = {
9
+ directives: {
10
+ tooltip: {
11
+ mounted() {
12
+ return undefined
13
+ },
14
+ },
15
+ },
16
+ }
17
+
18
+ describe('TablerIconButton', () => {
19
+ it('adds hover styling when no explicit color is provided', () => {
20
+ const wrapper = mount(IconButton, {
21
+ props: {
22
+ title: 'Toggle Panel',
23
+ },
24
+ slots: {
25
+ default: 'X',
26
+ },
27
+ global,
28
+ })
29
+
30
+ expect(wrapper.get('div').classes()).toContain('custom-hover')
31
+ })
32
+
33
+ it('skips hover styling when a custom color is provided', () => {
34
+ const wrapper = mount(IconButton, {
35
+ props: {
36
+ title: 'Toggle Panel',
37
+ color: '#123456',
38
+ },
39
+ slots: {
40
+ default: 'X',
41
+ },
42
+ global,
43
+ })
44
+
45
+ expect(wrapper.get('div').classes()).not.toContain('custom-hover')
46
+ })
47
+
48
+ it('uses CloudTAK light hover colors in light mode and inverted colors in dark mode', () => {
49
+ expect(iconButtonSource).toContain("[data-bs-theme='light'] .custom-hover:not(.disabled):hover,")
50
+ expect(iconButtonSource).toContain("[data-bs-theme='light'] .custom-hover:not(.disabled):focus-visible {")
51
+ expect(iconButtonSource).toContain('background-color: var(--cloudtak-light, rgba(var(--tblr-primary-rgb), 0.08));')
52
+ expect(iconButtonSource).toContain('color: var(--tblr-body-color);')
53
+
54
+ expect(iconButtonSource).toContain("[data-bs-theme='dark'] .custom-hover:not(.disabled):hover,")
55
+ expect(iconButtonSource).toContain("[data-bs-theme='dark'] .custom-hover:not(.disabled):focus-visible {")
56
+ expect(iconButtonSource).toContain('background-color: var(--tblr-light);')
57
+ expect(iconButtonSource).toContain('color: var(--tblr-dark);')
58
+ })
59
+ })
package/tsconfig.json CHANGED
@@ -4,20 +4,14 @@
4
4
  "module": "esnext",
5
5
  "strict": true,
6
6
  "jsx": "preserve",
7
- "moduleResolution": "node",
7
+ "moduleResolution": "bundler",
8
8
  "skipLibCheck": true,
9
9
  "esModuleInterop": true,
10
10
  "allowSyntheticDefaultImports": true,
11
11
  "forceConsistentCasingInFileNames": true,
12
12
  "useDefineForClassFields": true,
13
13
  "sourceMap": true,
14
- "baseUrl": ".",
15
- "types": [],
16
- "paths": {
17
- "@/*": [
18
- "src/*"
19
- ]
20
- }
14
+ "types": []
21
15
  },
22
16
  "include": [
23
17
  "lib.ts",