@inriver/inri 1.0.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.
Files changed (114) hide show
  1. package/.eslintrc.js +5 -0
  2. package/componentProperties.d.ts +8 -0
  3. package/configs/base-eslint-config.js +36 -0
  4. package/configs/base-tailwind-config.js +149 -0
  5. package/i18n.ts +11 -0
  6. package/index.ts +25 -0
  7. package/package.json +36 -0
  8. package/src/components/CAutoBreadcrumbs.vue +72 -0
  9. package/src/components/CBtn.vue +98 -0
  10. package/src/components/CColorPicker.vue +55 -0
  11. package/src/components/CContextMenu.vue +29 -0
  12. package/src/components/CDatePicker.vue +51 -0
  13. package/src/components/CDeleteTileBtn.vue +52 -0
  14. package/src/components/CDialog.vue +253 -0
  15. package/src/components/CDialogCloseBtn.vue +9 -0
  16. package/src/components/CDirtyCheck.vue +68 -0
  17. package/src/components/CDrawer.vue +44 -0
  18. package/src/components/CDrawerButton.vue +91 -0
  19. package/src/components/CExpansionItem.vue +57 -0
  20. package/src/components/CExpansionItemWithCheckbox.vue +41 -0
  21. package/src/components/CFileDropzone.vue +114 -0
  22. package/src/components/CGrid.vue +101 -0
  23. package/src/components/CHeader.vue +10 -0
  24. package/src/components/CHeaderLinks.vue +61 -0
  25. package/src/components/CHeaderMenuLink.vue +51 -0
  26. package/src/components/CHeaderSearch.vue +142 -0
  27. package/src/components/CIconBtn.vue +70 -0
  28. package/src/components/CMenuItem.vue +66 -0
  29. package/src/components/CPageContainer.vue +11 -0
  30. package/src/components/CPageError.vue +24 -0
  31. package/src/components/CPageSpinner.vue +18 -0
  32. package/src/components/CSearch.vue +45 -0
  33. package/src/components/CSection.vue +29 -0
  34. package/src/components/CSectionTitle.vue +8 -0
  35. package/src/components/CSelect.vue +208 -0
  36. package/src/components/CSlideEffect.vue +62 -0
  37. package/src/components/CSpinner.vue +107 -0
  38. package/src/components/CTableActions.vue +16 -0
  39. package/src/components/CTileBtn.vue +178 -0
  40. package/src/components/CTimePicker.vue +42 -0
  41. package/src/components/CToggleGridView.vue +26 -0
  42. package/src/components/CToggleSidebarBtn.vue +19 -0
  43. package/src/components/CTooltip.vue +44 -0
  44. package/src/components/CTreeNode.vue +39 -0
  45. package/src/components/cards/CBannerCard.vue +103 -0
  46. package/src/components/cards/CSmallCard.vue +149 -0
  47. package/src/components/internal-components/ConfirmDialog.vue +78 -0
  48. package/src/composables/useDialog.ts +47 -0
  49. package/src/composables/useDirtyCheck.ts +25 -0
  50. package/src/composables/useDoubleClickListener.ts +28 -0
  51. package/src/composables/useSelectable.ts +62 -0
  52. package/src/composables/useTruncateChips.ts +46 -0
  53. package/src/i18n/de/index.ts +17 -0
  54. package/src/i18n/en/index.ts +84 -0
  55. package/src/i18n/es/index.ts +7 -0
  56. package/src/i18n/fr/index.ts +7 -0
  57. package/src/init/initInriFramework.ts +25 -0
  58. package/src/init/useInriApp.ts +55 -0
  59. package/src/layouts/CLayoutBlank.vue +7 -0
  60. package/src/layouts/CLayoutWithBackButton.vue +50 -0
  61. package/src/layouts/CLayoutWithSidebars.vue +46 -0
  62. package/src/layouts/layout-fragments/CPageAutoBreadcrumbs.vue +6 -0
  63. package/src/layouts/layout-fragments/CPageBackButton.vue +18 -0
  64. package/src/layouts/layout-fragments/CPageBlank.vue +20 -0
  65. package/src/layouts/layout-fragments/CPageFlexCol.vue +5 -0
  66. package/src/layouts/layout-fragments/CPageLeftSidebar.vue +5 -0
  67. package/src/layouts/layout-fragments/CPageMainContent.vue +5 -0
  68. package/src/layouts/layout-fragments/CPageOuterWrapper.vue +5 -0
  69. package/src/layouts/layout-fragments/CPageRightSidebar.vue +5 -0
  70. package/src/layouts/layout-fragments/CPageTitle.vue +34 -0
  71. package/src/plugins/dialog.ts +45 -0
  72. package/src/plugins/errors/ErrorFactories.ts +59 -0
  73. package/src/plugins/errors/Errors.ts +156 -0
  74. package/src/plugins/errors/Exception.ts +6 -0
  75. package/src/plugins/errors/globalErrorHandler.ts +21 -0
  76. package/src/plugins/errors/handleError.ts +34 -0
  77. package/src/plugins/errors/logger.ts +16 -0
  78. package/src/plugins/errors/vueErrorHandler.ts +26 -0
  79. package/src/plugins/globalAppConfig.ts +25 -0
  80. package/src/plugins/i18n.ts +46 -0
  81. package/src/plugins/inriIcons.ts +58 -0
  82. package/src/plugins/inriverQuasarComponentConfigurations.ts +67 -0
  83. package/src/plugins/library.ts +119 -0
  84. package/src/plugins/notify.ts +153 -0
  85. package/src/plugins/quasar-user-options.ts +19 -0
  86. package/src/plugins/validationRules.ts +292 -0
  87. package/src/shims-vue.d.ts +6 -0
  88. package/src/stores/inriStore.ts +54 -0
  89. package/src/stores/interfaceLanguageStore.ts +27 -0
  90. package/src/styles/_css-variables.scss +101 -0
  91. package/src/styles/_reset.scss +67 -0
  92. package/src/styles/_transitions.scss +9 -0
  93. package/src/styles/_utils.scss +15 -0
  94. package/src/styles/components/_breadcrumbs.scss +3 -0
  95. package/src/styles/components/_checkboxes.scss +17 -0
  96. package/src/styles/components/_chips.scss +17 -0
  97. package/src/styles/components/_forms.scss +203 -0
  98. package/src/styles/components/_menu.scss +12 -0
  99. package/src/styles/components/_notifications.scss +24 -0
  100. package/src/styles/components/_q-editor.scss +14 -0
  101. package/src/styles/components/_radio-buttons.scss +17 -0
  102. package/src/styles/components/_tables.scss +92 -0
  103. package/src/styles/components/_tooltips.scss +5 -0
  104. package/src/styles/components/_tree.scss +86 -0
  105. package/src/styles/components/_truncated-chips.scss +39 -0
  106. package/src/styles/main.scss +45 -0
  107. package/src/styles/quasar.variables.scss +50 -0
  108. package/src/typings.d.ts +70 -0
  109. package/src/utils/colorUtils.ts +73 -0
  110. package/src/utils/errorUtils.ts +37 -0
  111. package/src/utils/fileUtils.ts +57 -0
  112. package/src/utils/helpers.ts +6 -0
  113. package/src/utils/routeUtils.ts +23 -0
  114. package/tsconfig.json +37 -0
@@ -0,0 +1,292 @@
1
+ import { i18n } from './i18n'
2
+
3
+ const $t = i18n.global.t
4
+
5
+ /**
6
+ * The value is required.
7
+ * @param {string} [msg] - Override the default error message
8
+ */
9
+ export function required (msg?: string) {
10
+ return (value): true | string => {
11
+ return !!value || msg || $t('inri.validation.required')
12
+ }
13
+ }
14
+
15
+ /**
16
+ * The value must have a minimum length.
17
+ * @param {string | number} length - Min length
18
+ * @param {string} [msg] - Override the default error message
19
+ */
20
+ export function minLength (length: string | number, msg?: string) {
21
+ const parsedLength = typeof length === 'number' ? length : parseInt(length, 10)
22
+ return (value): true | string => {
23
+ if (!value) {
24
+ return true
25
+ }
26
+
27
+ return value.length >= parsedLength || msg || $t('inri.validation.minLength', { parsedLength: parsedLength })
28
+ }
29
+ }
30
+
31
+ /**
32
+ * The value can not exceed maximum length.
33
+ * @param {string | number} length - Max length
34
+ * @param {string} [msg] - Override the default error message
35
+ */
36
+ export function maxLength (length: string | number, msg?: string) {
37
+ const parsedLength = typeof length === 'number' ? length : parseInt(length, 10)
38
+ return (value): true | string => {
39
+ if (!value) {
40
+ return true
41
+ }
42
+
43
+ return value.length <= parsedLength || msg || $t('inri.validation.maxLength', { parsedLength: parsedLength })
44
+ }
45
+ }
46
+
47
+ /**
48
+ * The value must be a valid email.
49
+ * @param {string} [msg] - Override the default error message
50
+ */
51
+ export function email (msg?: string) {
52
+ // eslint-disable-next-line no-useless-escape
53
+ const regExp = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
54
+ return (value): true | string => {
55
+ if (!value) {
56
+ return true
57
+ }
58
+
59
+ return regExp.test(String(value).toLowerCase()) || msg || $t('inri.validation.email')
60
+ }
61
+ }
62
+
63
+ /**
64
+ * The value must be a valid url.
65
+ * @param {string} [msg] - Override the default error message
66
+ */
67
+ export function url (msg?: string) {
68
+ // eslint-disable-next-line no-useless-escape
69
+ const regExp = /^(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*))$/
70
+ return (value): true | string => {
71
+ if (!value) {
72
+ return true
73
+ }
74
+
75
+ return regExp.test(String(value).toLowerCase()) || msg || $t('inri.validation.url')
76
+ }
77
+ }
78
+
79
+ /**
80
+ * The value must be a valid url using https.
81
+ * @param {string} [msg] - Override the default error message
82
+ */
83
+ export function https (msg?: string) {
84
+ // eslint-disable-next-line no-useless-escape
85
+ const regExp = /^(https:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*))$/
86
+ return (value): true | string => {
87
+ if (!value) {
88
+ return true
89
+ }
90
+
91
+ return regExp.test(String(value).toLowerCase()) || msg || $t('inri.validation.https')
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Validate file extensions. Supports single and multiple files.
97
+ * @param {string} fileExtensions - A string containing a single file extension, "jpg", or a comma separated string, "jpg,png".
98
+ * @param {string} [msg] - Override the default error message
99
+ */
100
+ export function extension (fileExtensions: string, msg?: string) {
101
+ // Extension string cleanup and convert to array
102
+ const extensions = fileExtensions
103
+ .toLowerCase()
104
+ .replaceAll(' ', '')
105
+ .replaceAll('.', '')
106
+ .split(',')
107
+
108
+ return (value): true | string => {
109
+ if (!value) {
110
+ return true
111
+ }
112
+
113
+ let files: any[] = []
114
+ let isValid = true
115
+
116
+ // If single file then push it into an array for consistency
117
+ if (!value.length) {
118
+ files.push(value)
119
+ } else {
120
+ files = value
121
+ }
122
+
123
+ for (const file of files) {
124
+ const fileExt = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase()
125
+ if (!extensions.includes(fileExt)) {
126
+ isValid = false
127
+ break
128
+ }
129
+ }
130
+
131
+ return isValid || msg || $t('inri.validation.extension', { extensions: extensions.join(', .') })
132
+ }
133
+ }
134
+
135
+ /**
136
+ * The value must contain all the strings in the array.
137
+ * @param {string[]} arr - Array of strings.
138
+ * @param {boolean} caseSensitive
139
+ * @param {string} [msg] - Override the default error message
140
+ */
141
+ export function contains (arr: string[], caseSensitive = false, msg?: string) {
142
+ return (value): true | string => {
143
+ if (!value) {
144
+ return true
145
+ }
146
+
147
+ let foundItems
148
+
149
+ if (!caseSensitive) {
150
+ foundItems = arr.filter(item => !value.toUpperCase().includes(('' + item).toUpperCase()))
151
+ } else {
152
+ foundItems = arr.filter(item => !value.includes('' + item))
153
+ }
154
+
155
+ if (!foundItems.length) {
156
+ return true
157
+ }
158
+
159
+ return msg || $t('inri.validation.contains', { match: foundItems.join(', ') })
160
+ }
161
+ }
162
+
163
+ /**
164
+ * The value must not contain any of the strings in the array.
165
+ * @param {string[]} arr - Array of strings.
166
+ * @param {boolean} caseSensitive
167
+ * @param {string} [msg] - Override the default error message
168
+ */
169
+ export function notContains (arr: string[], caseSensitive = false, msg?: string) {
170
+ return (value): true | string => {
171
+ if (!value) {
172
+ return true
173
+ }
174
+
175
+ const comparisonValue = value instanceof File ? value.name : value
176
+
177
+ let foundItems
178
+
179
+ if (!caseSensitive) {
180
+ foundItems = arr.filter(item => comparisonValue.toUpperCase().includes(('' + item).toUpperCase()))
181
+ } else {
182
+ foundItems = arr.filter(item => comparisonValue.includes('' + item))
183
+ }
184
+
185
+ if (!foundItems.length) {
186
+ return true
187
+ }
188
+
189
+ return msg || $t('inri.validation.notContains', { match: foundItems.join(', ') })
190
+ }
191
+ }
192
+
193
+ /**
194
+ * The value must not begin with any of the strings in the array.
195
+ * @param {string[]} arr - Array of strings.
196
+ * @param {boolean} caseSensitive
197
+ * @param {string} [msg] - Override the default error message
198
+ */
199
+ export function notBeginsWith (arr: string[], caseSensitive = false, msg?: string) {
200
+ return (value): true | string => {
201
+ if (!value) {
202
+ return true
203
+ }
204
+
205
+ let foundItems
206
+
207
+ if (!caseSensitive) {
208
+ foundItems = arr.filter(item => value.toUpperCase().startsWith(('' + item).toUpperCase()))
209
+ } else {
210
+ foundItems = arr.filter(item => value.startsWith('' + item))
211
+ }
212
+
213
+ if (!foundItems.length) {
214
+ return true
215
+ }
216
+
217
+ return msg || $t('inri.validation.notBeginsWith', { match: foundItems.join(', ') })
218
+ }
219
+ }
220
+
221
+ /**
222
+ * The value must not end with any of the strings in the array.
223
+ * @param {string[]} arr - Array of strings.
224
+ * @param {boolean} caseSensitive
225
+ * @param {string} [msg] - Override the default error message
226
+ */
227
+ export function notEndsWith (arr: string[], caseSensitive = false, msg?: string) {
228
+ return (value): true | string => {
229
+ if (!value) {
230
+ return true
231
+ }
232
+
233
+ let foundItems
234
+
235
+ if (!caseSensitive) {
236
+ foundItems = arr.filter(item => value.toUpperCase().endsWith(('' + item).toUpperCase()))
237
+ } else {
238
+ foundItems = arr.filter(item => value.endsWith('' + item))
239
+ }
240
+
241
+ if (!foundItems.length) {
242
+ return true
243
+ }
244
+
245
+ return msg || $t('inri.validation.notEndsWith', { match: foundItems.join(', ') })
246
+ }
247
+ }
248
+
249
+ /**
250
+ * The file(s) cannot exceed max size
251
+ * @param {string | number} size - Max size in bytes
252
+ * @param {string} [type] - Only validate against files with this MIME type
253
+ * @param {string} [msg] - Override the default error message
254
+ */
255
+ export function maxFileSize (size: string | number, type?: string, msg?: string) {
256
+ const parsedFileSize = typeof size === 'number' ? size : parseInt(size, 10)
257
+
258
+ return (value): true | string => {
259
+ if (!value) {
260
+ return true
261
+ }
262
+
263
+ let files: any[] = []
264
+
265
+ if (!value.length) {
266
+ files.push(value)
267
+ } else {
268
+ files = value
269
+ }
270
+
271
+ if (type) {
272
+ files = files.filter(file => file.type.includes(type))
273
+ }
274
+
275
+ return files.every(file => file.size <= size) || msg || $t('inri.validation.maxFileSize', { parsedFileSize })
276
+ }
277
+ }
278
+
279
+ export const rules = {
280
+ required,
281
+ maxLength,
282
+ minLength,
283
+ email,
284
+ url,
285
+ https,
286
+ extension,
287
+ contains,
288
+ notContains,
289
+ notBeginsWith,
290
+ notEndsWith,
291
+ maxFileSize,
292
+ }
@@ -0,0 +1,6 @@
1
+ /* eslint-disable */
2
+ declare module '*.vue' {
3
+ import type { DefineComponent } from 'vue'
4
+ const component: DefineComponent<{}, {}, any>
5
+ export default component
6
+ }
@@ -0,0 +1,54 @@
1
+ import { computed, reactive } from 'vue'
2
+
3
+ interface State {
4
+ dirtyComponents: any[],
5
+ leftDrawerIsOpen: boolean,
6
+ rightDrawerIsOpen: boolean,
7
+ showSidebar: boolean,
8
+ showPageSpinner: boolean,
9
+ isGridView: boolean
10
+ }
11
+
12
+ const state = reactive<State>({
13
+ dirtyComponents: [],
14
+ leftDrawerIsOpen: false,
15
+ rightDrawerIsOpen: false,
16
+ showSidebar: true,
17
+ showPageSpinner: false,
18
+ isGridView: true,
19
+ })
20
+
21
+ const isAnyDirty = computed(() => {
22
+ return !!state.dirtyComponents.length
23
+ })
24
+
25
+ function toggleLeftDrawer () {
26
+ state.leftDrawerIsOpen = !state.leftDrawerIsOpen
27
+ }
28
+
29
+ function toggleRightDrawer () {
30
+ state.rightDrawerIsOpen = !state.rightDrawerIsOpen
31
+ }
32
+
33
+ function toggleSidebar () {
34
+ state.showSidebar = !state.showSidebar
35
+ }
36
+
37
+ function toggleDirtyComponent (item: any, add: boolean | undefined) {
38
+ if (add && !state.dirtyComponents.find(i => i === item)) {
39
+ state.dirtyComponents.push(item)
40
+ } else {
41
+ state.dirtyComponents = state.dirtyComponents.filter(i => i !== item)
42
+ }
43
+ }
44
+
45
+ export const useInriStore = () => {
46
+ return {
47
+ state,
48
+ isAnyDirty,
49
+ toggleLeftDrawer,
50
+ toggleRightDrawer,
51
+ toggleSidebar,
52
+ toggleDirtyComponent,
53
+ }
54
+ }
@@ -0,0 +1,27 @@
1
+ import { defineStore } from 'pinia'
2
+ import { Quasar } from 'quasar'
3
+ import { loadi18nLanguageAsync } from '../plugins/i18n'
4
+
5
+ export const useInterfaceLanguageStore = defineStore({
6
+ id: 'interfaceLanguage',
7
+ state: () => ({}),
8
+ actions: {
9
+ async loadQuasarLanguageAsync (lang: string) {
10
+ // IMPORTANT: Quasar uses "en-US" instead of "en"
11
+ const qLangCode = lang === 'en' ? 'en-US' : lang
12
+
13
+ const qLang = await import(
14
+ /* webpackInclude: /(de|en-US|fr|es)\.js$/ */
15
+ 'quasar/lang/' + qLangCode
16
+ )
17
+ Quasar.lang.set(qLang.default)
18
+ },
19
+ async setLanguage (lang : string) {
20
+ await loadi18nLanguageAsync(lang)
21
+ await this.loadQuasarLanguageAsync(lang)
22
+ },
23
+ async init (lang: string) {
24
+ await this.setLanguage(lang)
25
+ },
26
+ },
27
+ })
@@ -0,0 +1,101 @@
1
+ :root {
2
+ /* stylelint-disable-next-line */
3
+ --font-family: 'Wallop', 'Roboto', '-apple-system', 'Helvetica Neue', Helvetica, Arial, sans-serif;
4
+
5
+ // Color palette
6
+ --color-grey: #ccc;
7
+ --color-grey-light: #ddd;
8
+ --color-grey-lighter: #eaeaea;
9
+ --color-grey-10: #f3f3f3;
10
+ --color-grey-dark: #888;
11
+ --color-grey-darker: #444;
12
+ --color-grey-darkest: #2d2d2c;
13
+ --color-blue: #4799fc;
14
+ --color-blue-light: #91c2fd;
15
+ --color-purple: #ad66f2;
16
+ --color-purple-light: #cea3f7;
17
+ --color-red: #ff3838;
18
+ --color-red-light: #ff8888;
19
+ --color-orange: #ff7a20;
20
+ --color-orange-light: #ffa874;
21
+ --color-yellow: #ffbf2e;
22
+ --color-yellow-light: #ffd982;
23
+ --color-green: #00b06e;
24
+ --color-green-light: #66d0a8;
25
+ --color-green-light-30: rgba(102,208,168,0.3);
26
+ --color-green-10: #e5f7f0;
27
+
28
+ // Surface is a special color defined in Material Design but not part of Quasar. We still want to use it though.
29
+ // This is any plain surface, like a card or dialog background.
30
+ --surface-color: #fff;
31
+ --on-surface-color: var(--color-grey-darkest);
32
+ --surface-effect-color: var(--color-grey-lighter);
33
+ --surface-border-color: var(--color-grey);
34
+
35
+ // ** Primary, secondary and accent colors **
36
+ // Quasar base colors, like primary, are defined in quasar.variables.scss but can be overwritten like this: "--q-primary: orange !important;"
37
+
38
+ // primary = black
39
+ --on-primary-color: #fff;
40
+ --on-primary-alt-color: #fff; // This alt color is used in some scenarios, like for the context menu on banner cards.
41
+ --primary-effect-color: var(--color-grey-darker);
42
+
43
+ // secondary = grey-lighter
44
+ --on-secondary-color: var(--color-grey-darkest);
45
+ --on-secondary-alt-color: var(--color-grey-darkest);
46
+ --secondary-effect-color: var(--color-grey-light);
47
+
48
+ // accent = green
49
+ --on-accent-color: var(--color-grey-darkest);
50
+ --on-accent-alt-color: #fff;
51
+ --accent-effect-color: var(--color-green-light);
52
+
53
+ // Color aliases
54
+ --color-text: var(--color-grey-darkest);
55
+ --color-border: var(--color-grey-light);
56
+ --color-border-dark: var(--color-grey);
57
+
58
+ // Form elements
59
+ --input-bg-color: var(--surface-color);
60
+ --checkbox-border-color: var(--color-grey);
61
+ --radio-border-color: var(--color-grey);
62
+
63
+ // Table
64
+ --table-header-bg-color: var(--surface-color);
65
+ --table-image-size-width: 45px;
66
+ --table-image-size-height: 35px;
67
+
68
+ // Tree
69
+ --tree-icon-color: var(--color-grey-dark);
70
+ --tree-text-color: var(--color-text);
71
+
72
+ // Small card
73
+ --small-card-image-size: 86px;
74
+
75
+ // Tooltip
76
+ --tooltip-bg-color: #fff;
77
+ --tooltip-text-color: var(--color-grey-darkest);
78
+ --tooltip-border-color: var(--color-grey);
79
+
80
+ // Generic item states (lists/tables/trees etc.)
81
+ --item-selected-bg-color: var(--color-green-10);
82
+ --item-hover-bg-color: var(--color-grey-10);
83
+
84
+ // Dialog
85
+ --dialog-shadow: 0 2px 27px rgba(0, 0, 0, 0.25);
86
+ --dialog-backdrop-color: rgba(0, 0, 0, 0.25);
87
+
88
+ // Chips
89
+ --chip-bg-color: var(--color-grey-lighter);
90
+ --chip-text-color: var(--color-grey-darkest);
91
+
92
+ // Misc
93
+ --breadcrumbs-separator-color: var(--color-grey);
94
+ }
95
+
96
+ // Themes for different sections of the application
97
+ [theme='route-demo-theme'] {
98
+ --q-primary: var(--color-green);
99
+ --q-secondary: var(--color-green-light);
100
+ --q-accent: var(--color-green-light);
101
+ }
@@ -0,0 +1,67 @@
1
+ body {
2
+ color: var(--color-text);
3
+ font-variant-ligatures: none;
4
+ }
5
+
6
+ // Reset browser heading margin
7
+ h1,
8
+ h2,
9
+ h3,
10
+ h4,
11
+ h5,
12
+ h6 {
13
+ margin: 0;
14
+ }
15
+
16
+ code {
17
+ background: var(--color-grey-darkest);
18
+ color: white;
19
+ border-radius: 4px;
20
+ padding: 0 4px;
21
+ }
22
+
23
+ pre {
24
+ margin: 0;
25
+ }
26
+
27
+ // Copied from Preflight/Windi reset
28
+ *,
29
+ ::before,
30
+ ::after {
31
+ border-width: 0;
32
+ border-style: solid;
33
+ border-color: var(--color-border);
34
+ }
35
+
36
+ [placeholder]::placeholder {
37
+ color: var(--color-grey);
38
+ opacity: 1; /* Firefox */
39
+ }
40
+
41
+ // Custom scrollbar in Firefox
42
+ * {
43
+ scrollbar-width: thin;
44
+ }
45
+
46
+ // Custom scrollbar in Chrome/Webkit
47
+ ::-webkit-scrollbar-thumb {
48
+ border-radius: 4px;
49
+ background-color: var(--color-grey);
50
+ }
51
+
52
+ ::-webkit-scrollbar {
53
+ width: 8px;
54
+ height: 8px;
55
+ }
56
+
57
+ a {
58
+ text-decoration: none;
59
+ color: var(--on-surface-color);
60
+ }
61
+
62
+ ol,
63
+ ul {
64
+ list-style: none;
65
+ margin: 0;
66
+ padding: 0;
67
+ }
@@ -0,0 +1,9 @@
1
+ .fade-enter-active,
2
+ .fade-leave-active {
3
+ transition: opacity 0.3s;
4
+ }
5
+
6
+ .fade-enter-from,
7
+ .fade-leave-to {
8
+ opacity: 0;
9
+ }
@@ -0,0 +1,15 @@
1
+ // There is a plugin in windi for this, but for some reason it breaks code completion
2
+ .line-clamp-2 {
3
+ overflow: hidden;
4
+ display: -webkit-box;
5
+ -webkit-box-orient: vertical;
6
+ -webkit-line-clamp: 2;
7
+ }
8
+
9
+ .overflow-y-overlay {
10
+ // Fallback to auto in Firefox
11
+ overflow-y: auto;
12
+
13
+ // Overlay in Chrome
14
+ overflow-y: overlay;
15
+ }
@@ -0,0 +1,3 @@
1
+ .q-breadcrumbs__separator {
2
+ color: var(--breadcrumbs-separator-color);
3
+ }
@@ -0,0 +1,17 @@
1
+ .c-checkbox {
2
+ &.q-checkbox[aria-label] {
3
+ max-width: max-content;
4
+ }
5
+
6
+ &.q-checkbox.disabled {
7
+ opacity: 0.4 !important;
8
+ }
9
+
10
+ .q-checkbox__inner--falsy .q-checkbox__bg {
11
+ border: 2px solid var(--checkbox-border-color);
12
+ }
13
+
14
+ .q-checkbox__label {
15
+ padding: 4px 10px;
16
+ }
17
+ }
@@ -0,0 +1,17 @@
1
+ .q-chip {
2
+ background: var(--chip-bg-color);
3
+ color: var(--chip-text-color);
4
+ height: 26px;
5
+
6
+ .q-chip__icon--remove {
7
+ margin-left: 8px;
8
+ }
9
+
10
+ .q-chip__icon {
11
+ opacity: 0.25;
12
+ }
13
+ }
14
+
15
+ .q-chip--dense {
16
+ padding: 0 8px;
17
+ }