@konoma-development/vue-components 0.0.1

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 (55) hide show
  1. package/.nuxtrc +1 -0
  2. package/.playground/app.vue +64 -0
  3. package/.playground/eslint.config.ts +3 -0
  4. package/.playground/nuxt.config.ts +9 -0
  5. package/.tool-versions +1 -0
  6. package/.vscode/extensions.json +9 -0
  7. package/.vscode/settings.json +12 -0
  8. package/README.md +70 -0
  9. package/app.config.ts +13 -0
  10. package/components/KonomaTheme.vue +92 -0
  11. package/components/defaults/button.ts +19 -0
  12. package/components/defaults/checkbox.ts +13 -0
  13. package/components/defaults/checkboxList.ts +9 -0
  14. package/components/defaults/columnChooser.ts +8 -0
  15. package/components/defaults/input.ts +16 -0
  16. package/components/defaults/pagination.ts +10 -0
  17. package/components/defaults/radioButtonGroup.ts +13 -0
  18. package/components/defaults/select.ts +20 -0
  19. package/components/defaults/table.ts +16 -0
  20. package/components/defaults/tabs.ts +10 -0
  21. package/components/defaults/tag.ts +7 -0
  22. package/components/defaults/tagList.ts +14 -0
  23. package/components/defaults/textarea.ts +16 -0
  24. package/components/form/KonomaCheckbox.vue +68 -0
  25. package/components/form/KonomaCheckboxList.vue +42 -0
  26. package/components/form/KonomaForm.vue +71 -0
  27. package/components/form/KonomaFormField.vue +36 -0
  28. package/components/form/KonomaInput.vue +92 -0
  29. package/components/form/KonomaPhoneInput.vue +9 -0
  30. package/components/form/KonomaRadioButtonGroup.vue +41 -0
  31. package/components/form/KonomaSelect.vue +9 -0
  32. package/components/form/KonomaTagList.vue +55 -0
  33. package/components/form/KonomaTextarea.vue +81 -0
  34. package/components/form/injectionKeys.ts +8 -0
  35. package/components/table/KonomaColumnChooser.vue +64 -0
  36. package/components/table/KonomaColumnChooserEntry.vue +18 -0
  37. package/components/table/KonomaPagination.vue +81 -0
  38. package/components/table/KonomaTable.vue +355 -0
  39. package/components/table/KonomaTableActionEntry.vue +27 -0
  40. package/components/table/KonomaTableActions.vue +32 -0
  41. package/components/ui/KonomaButton.vue +109 -0
  42. package/components/ui/KonomaIcon.vue +13 -0
  43. package/components/ui/KonomaLoadingIndicator.vue +14 -0
  44. package/components/ui/KonomaModal.vue +120 -0
  45. package/components/ui/KonomaTabs.vue +70 -0
  46. package/components/ui/KonomaTag.vue +49 -0
  47. package/composables/useKonomaTheme.ts +5 -0
  48. package/eslint.config.ts +43 -0
  49. package/index.d.ts +33 -0
  50. package/nuxt.config.ts +20 -0
  51. package/package.json +60 -0
  52. package/tsconfig.json +11 -0
  53. package/types/form.ts +149 -0
  54. package/types/table.ts +33 -0
  55. package/unocss.config.ts +83 -0
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <div :class="wrapperClasses">
3
+ <div
4
+ v-for="(tab, i) in tabs"
5
+ :key="i"
6
+ :class="[
7
+ tabBaseClasses,
8
+ equalTabs(tab.id, active) ? tabActiveClasses : tabInactiveClasses,
9
+ ]"
10
+ @click="$emit('click', tab.id)"
11
+ >
12
+ <span>{{ tab.label }}</span>
13
+ <div
14
+ v-if="showCounts"
15
+ :class="[
16
+ countBaseClasses,
17
+ equalTabs(tab.id, active) ? countActiveClasses : countInactiveClasses,
18
+ ]"
19
+ >
20
+ {{ tab.count }}
21
+ </div>
22
+ <div v-if="equalTabs(tab.id, active)" :class="activeMarkerClass" />
23
+ </div>
24
+ </div>
25
+ </template>
26
+
27
+ <script lang="ts" setup generic="DataType">
28
+ import { baseClasses } from '../defaults/tabs';
29
+
30
+ interface Tab<DataType> {
31
+ id: DataType
32
+ label: string
33
+ count: number
34
+ }
35
+
36
+ withDefaults(defineProps<{
37
+ wrapperClasses?: string
38
+ tabActiveClasses?: string
39
+ tabInactiveClasses?: string
40
+ countActiveClasses?: string
41
+ countInactiveClasses?: string
42
+ tabBaseClasses?: string
43
+ countBaseClasses?: string
44
+ activeMarkerClass?: string
45
+ showCounts?: boolean
46
+ tabs: Tab<DataType>[]
47
+ active: DataType
48
+ }>(), {
49
+ wrapperClasses: baseClasses.wrapperClasses,
50
+ tabActiveClasses: baseClasses.tabActiveClasses,
51
+ tabInactiveClasses: baseClasses.tabInactiveClasses,
52
+ countActiveClasses: baseClasses.countActiveClasses,
53
+ countInactiveClasses: baseClasses.countInactiveClasses,
54
+ tabBaseClasses: baseClasses.tabBaseClasses,
55
+ countBaseClasses: baseClasses.countBaseClasses,
56
+ activeMarkerClass: baseClasses.activeMarkerClasses,
57
+ showCounts: true,
58
+ })
59
+
60
+ defineEmits<{
61
+ (e: 'click', tab: DataType): void
62
+ }>()
63
+
64
+ function equalTabs<DataType>(tab1: DataType, tab2: DataType) {
65
+ if (Array.isArray(tab1) && Array.isArray(tab2)) {
66
+ return tab1.length === tab2.length && tab1.every((value, index) => value === tab2[index])
67
+ }
68
+ return tab1 === tab2
69
+ }
70
+ </script>
@@ -0,0 +1,49 @@
1
+ <template>
2
+ <div :class="wrapperClasses" @click="$emit('click')">
3
+ <KonomaIcon
4
+ v-if="iconLeftPath || iconLeftName"
5
+ :name="iconLeftName"
6
+ :path="iconLeftPath"
7
+ :class="iconLeftClasses"
8
+ @click="$emit('clickIconLeft')"
9
+ />
10
+ <div :class="titleClasses">
11
+ {{ title }}
12
+ </div>
13
+ <KonomaIcon
14
+ v-if="iconRightPath || iconRightName"
15
+ :name="iconRightName"
16
+ :path="iconRightPath"
17
+ :class="iconRightClasses"
18
+ @click="$emit('clickIconRight')"
19
+ />
20
+ </div>
21
+ </template>
22
+
23
+ <script lang="ts" setup>
24
+ import { baseClasses } from '../defaults/tag';
25
+ import KonomaIcon from './KonomaIcon.vue'
26
+
27
+ withDefaults(defineProps<{
28
+ wrapperClasses?: string
29
+ titleClasses?: string
30
+ iconLeftClasses?: string
31
+ iconRightClasses?: string
32
+ iconLeftPath?: string
33
+ iconLeftName?: string
34
+ iconRightPath?: string
35
+ iconRightName?: string
36
+ title: string
37
+ }>(), {
38
+ wrapperClasses: baseClasses.wrapperClasses,
39
+ titleClasses: baseClasses.titleClasses,
40
+ iconLeftClasses: baseClasses.iconLeftClasses,
41
+ iconRightClasses: baseClasses.iconRightClasses,
42
+ })
43
+
44
+ defineEmits<{
45
+ (e: 'click'): void
46
+ (e: 'clickIconLeft'): void
47
+ (e: 'clickIconRight'): void
48
+ }>()
49
+ </script>
@@ -0,0 +1,5 @@
1
+ import { defineStore } from 'pinia';
2
+
3
+ export const useKonomaTheme = defineStore('konoma-theme', () => {
4
+ return {};
5
+ });
@@ -0,0 +1,43 @@
1
+ import antfu from '@antfu/eslint-config';
2
+ import * as eslint from '@eslint/js';
3
+ import * as globals from 'globals';
4
+ import * as vueParser from 'vue-eslint-parser';
5
+ import withNuxt from './.playground/.nuxt/eslint.config.mjs';
6
+
7
+ export default withNuxt(
8
+ eslint.configs.recommended,
9
+ await antfu({
10
+ unocss: true,
11
+ rules: {
12
+ 'style/semi': 'off',
13
+ 'style/brace-style': ['error', '1tbs'],
14
+ 'vue/block-order': [
15
+ 'error',
16
+ {
17
+ order: [['template', 'script'], 'style'],
18
+ },
19
+ ],
20
+ },
21
+ }),
22
+ {
23
+ files: ['**/*.{ts}'],
24
+ languageOptions: {
25
+ parser: vueParser,
26
+ parserOptions: {
27
+ ecmaVersion: 'latest',
28
+ parser: '@typescript-eslint/parser',
29
+ sourceType: 'module',
30
+ },
31
+ globals: {
32
+ ...globals.browser,
33
+ },
34
+ },
35
+ rules: {
36
+ 'no-console': 'off',
37
+ 'no-debugger': 'off',
38
+ 'vue/multi-word-component-names': 'off',
39
+ 'no-case-declarations': 'off',
40
+ },
41
+ ignores: ['.nuxt/*'],
42
+ },
43
+ );
package/index.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ declare module '@nuxt/schema' {
2
+ interface AppConfigInput {
3
+ 'konoma-theme'?: {
4
+ primary?: string
5
+ secondary?: string
6
+ tertiary?: string
7
+ gray?: string
8
+ success?: string
9
+ info?: string
10
+ alert?: string
11
+ error?: string
12
+ extra?: string
13
+ }
14
+ }
15
+ }
16
+
17
+ declare module '@nuxt/schema' {
18
+ interface AppConfig {
19
+ 'konoma-theme': {
20
+ primary: string
21
+ secondary: string
22
+ tertiary: string
23
+ gray: string
24
+ success: string
25
+ info: string
26
+ alert: string
27
+ error: string
28
+ extra: string
29
+ }
30
+ }
31
+ }
32
+
33
+ export {};
package/nuxt.config.ts ADDED
@@ -0,0 +1,20 @@
1
+ export default defineNuxtConfig({
2
+ devtools: {
3
+ enabled: true,
4
+ },
5
+ modules: ['@pinia/nuxt', '@unocss/nuxt', '@nuxt/icon', '@vueuse/nuxt', '@nuxt/eslint', 'floating-vue/nuxt'],
6
+ vite: {},
7
+ experimental: {
8
+ asyncContext: true,
9
+ },
10
+ components: {
11
+ dirs: ['components/ui', 'components/form', 'components/table'],
12
+ },
13
+ compatibilityDate: '2024-07-06',
14
+ hooks: {},
15
+ eslint: {
16
+ config: {
17
+ standalone: false,
18
+ },
19
+ },
20
+ });
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@konoma-development/vue-components",
3
+ "version": "0.0.1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "packageManager": "yarn@4.12.0",
8
+ "main": "./nuxt.config.ts",
9
+ "scripts": {
10
+ "dev": "nuxi dev .playground",
11
+ "build": "nuxt build .playground",
12
+ "generate": "nuxt generate .playground",
13
+ "preview": "nuxt preview .playground",
14
+ "lint": "eslint .",
15
+ "upgrade-nuxt": "nuxi upgrade",
16
+ "upgrade-deps": "yarn dlx taze major -w",
17
+ "upgrade-all": "yarn upgrade-nuxt && yarn upgrade-deps"
18
+ },
19
+ "devDependencies": {
20
+ "@antfu/eslint-config": "7.6.1",
21
+ "@babel/eslint-parser": "7.28.6",
22
+ "@babel/plugin-transform-typescript": "7.28.6",
23
+ "@babel/preset-typescript": "7.28.5",
24
+ "@iconify-json/carbon": "1.2.18",
25
+ "@nuxt/devtools": "3.2.2",
26
+ "@nuxt/eslint": "1.15.2",
27
+ "@nuxt/eslint-config": "1.15.2",
28
+ "@nuxt/icon": "2.2.1",
29
+ "@nuxt/schema": "4.3.1",
30
+ "@nuxt/test-utils": "4.0.0",
31
+ "@nuxtjs/eslint-config-typescript": "12.1.0",
32
+ "@pinia/nuxt": "0.11.3",
33
+ "@sentry/nuxt": "10.40.0",
34
+ "@types/node": "22.19.12",
35
+ "@typescript-eslint/eslint-plugin": "8.56.1",
36
+ "@typescript-eslint/parser": "8.56.1",
37
+ "@unocss/eslint-config": "66.6.2",
38
+ "@unocss/nuxt": "66.6.2",
39
+ "@unocss/reset": "66.6.2",
40
+ "@vitejs/plugin-vue": "6.0.4",
41
+ "@vueuse/nuxt": "14.2.1",
42
+ "babel-preset-vue": "2.0.2",
43
+ "changelogen": "0.6.2",
44
+ "eslint": "10.0.2",
45
+ "eslint-plugin-nuxt": "4.0.0",
46
+ "eslint-plugin-unocss": "0.0.1-alpha.3",
47
+ "eslint-plugin-vue": "10.8.0",
48
+ "floating-vue": "5.2.2",
49
+ "nuxt": "4.3.1",
50
+ "nuxt-headlessui": "1.2.2",
51
+ "pinia": "3.0.4",
52
+ "tslib": "2.8.1",
53
+ "typescript": "5.9.3",
54
+ "unocss": "66.6.2",
55
+ "unocss-preset-scrollbar": "3.2.0",
56
+ "vite": "7.3.1",
57
+ "vue-eslint-parser": "10.4.0",
58
+ "vue-tsc": "3.2.5"
59
+ }
60
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "./.playground/.nuxt/tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "ESNext",
5
+ "types": [
6
+ "@pinia/nuxt"
7
+ ],
8
+ "noImplicitAny": true,
9
+ "allowSyntheticDefaultImports": true
10
+ }
11
+ }
package/types/form.ts ADDED
@@ -0,0 +1,149 @@
1
+ type LabelPosition = 'top' | 'bottom' | 'left' | 'right';
2
+
3
+ export interface FormDataType {
4
+ [key: string]: string | number | boolean | null
5
+ }
6
+
7
+ export type FormValue = string | number | boolean | Option;
8
+
9
+ export interface Option {
10
+ value: FormValue
11
+ label: string | number
12
+ }
13
+
14
+ /** Classes for the form components. Not all classes have effects in all components. Properties that start with 'class-' apply to the component in general, other properties apply to specific parts of the component */
15
+ export interface Classes {
16
+ class?: string
17
+ /** Base classes, usually assigned to the control */
18
+ classes?: string
19
+ /** Base classes, assigned directly to the control. Might be needed in case of more complex nesting */
20
+ controlClasses?: string
21
+ /** Used for components that have specific styling when in neutral state */
22
+ classesNeutral?: string
23
+ /** Used for components that have specific styling when empty */
24
+ classesEmpty?: string
25
+ classesDisabled?: string
26
+ /** Used for components that have specific styling when in error */
27
+ classesError?: string
28
+ /** Used for components that have specific styling when filled */
29
+ classesFilled?: string
30
+ /** Used for the label in components that have specific styling when empty */
31
+ labelClassesEmpty?: string
32
+ /** Used for the label in components that have specific styling when in error */
33
+ labelClassesError?: string
34
+ /** Used for the label in components that have specific styling when filled */
35
+ labelClassesFilled?: string
36
+ /** General classes for the label */
37
+ labelClasses?: string
38
+ /** Needed in case of nested label */
39
+ labelWrapperClasses?: string
40
+ /** Used for the icon in components that have specific styling when filled */
41
+ iconClassesFilled?: string
42
+ /** General classes for the wrapper */
43
+ wrapperClasses?: string
44
+ /** General classes for the icon on the left */
45
+ iconLeftClasses?: string
46
+ /** General classes for the icon on the right */
47
+ iconRightClasses?: string
48
+ /** General classes for the error message */
49
+ errorClasses?: string
50
+ /** Additional classes for the control when an icon is present on the left */
51
+ additionalClassesIconLeft?: string
52
+ /** Additional classes for the control when an icon is present on the right */
53
+ additionalClassesIconRight?: string
54
+ /** General classes for hints placed within the component */
55
+ hintClasses?: string
56
+ /** General classes for the resize element */
57
+ resizeClasses?: string
58
+ /** General classes for the icon within the resize element */
59
+ resizeIconClasses?: string
60
+ /** Classes to be applied to all values for components with multiple possible values */
61
+ optionClasses?: string
62
+ /** Classes to be applied to the wrapper for elements on the left side */
63
+ wrapperLeftClasses?: string
64
+ /** Classes to be applied to the wrapper for elements on the right side */
65
+ wrapperRightClasses?: string
66
+ // Properties for classes specific to the select component since it is effectively an Omnibox that is more complex than the other form components
67
+ focusClasses?: string
68
+ optionFocusedClasses?: string
69
+ optionSelectedClasses?: string
70
+ valueClasses?: string
71
+ placeholderClasses?: string
72
+ indicatorClasses?: string
73
+ valueContainerClasses?: string
74
+ }
75
+
76
+ export interface FormFieldEmits {
77
+ (e: 'forgotPWAction', event: MouseEvent): void
78
+ (e: 'blur', event: FocusEvent): void
79
+ (e: 'focus', event: FocusEvent): void
80
+ (e: 'change', value: FormValue | FormValue[], event?: Event): void
81
+ (e: 'input', value: FormValue, event?: InputEvent): void
82
+ (e: 'click', event: MouseEvent): void
83
+ (e: 'iconRightClick', event: MouseEvent): void
84
+ (e: 'iconLeftClick'): void
85
+ (e: 'keyDown', event: KeyboardEvent): void
86
+ }
87
+
88
+ export interface FormFieldProps<DataType extends {
89
+ [key: string]: string | number | boolean | null
90
+ }> extends Classes {
91
+ allowCustomValues?: boolean
92
+ customValueLabel?: string
93
+ arrangement?: 'horizontal' | 'vertical'
94
+ centered?: boolean
95
+ autoFocus?: boolean
96
+ childClasses?: {
97
+ [key in keyof Classes]?: string
98
+ }
99
+ defaultValue?: FormValue
100
+ disabled?: boolean
101
+ error?: string[]
102
+ forgotPWText?: string
103
+ iconLeftPath?: string
104
+ iconLeftName?: string
105
+ iconRightPath?: string
106
+ iconRightName?: string
107
+ indeterminate?: boolean
108
+ isClearable?: boolean
109
+ replacements?: Record<string, string>
110
+ labelPosition?: LabelPosition
111
+ maxLength?: number
112
+ maxLengthLabel?: string
113
+ name?: keyof DataType
114
+ options?: Option[]
115
+ placeholder?: string
116
+ required?: boolean
117
+ resizeIconPath?: string
118
+ resizeIconName?: string
119
+ addTagTitle?: string
120
+ searchable?: boolean
121
+ textRight?: string
122
+ type?: HTMLInputElement['type']
123
+ step?: HTMLInputElement['step']
124
+ initialHeight?: number
125
+ mask?: Mask | Mask[]
126
+ min?: number
127
+ max?: number
128
+ /** Used for components that bind to one value */
129
+ value?: FormValue
130
+ /** Used for components that bind to multiple values */
131
+ values?: FormValue[]
132
+ /** Used for selects that have no visible selected value */
133
+ noValue?: boolean
134
+ isMulti?: boolean
135
+ /** [select only] Default placement of the menu in relation to the control. 'auto' will flip when there isn't enough space below the control. */
136
+ menuPlacement?: 'auto' | 'top' | 'bottom'
137
+ /** Used to place the dropdown element of a Select */
138
+ menuPortalTarget?: HTMLElement
139
+
140
+ }
141
+
142
+ export const positionClasses: Record<LabelPosition, string> = {
143
+ top: 'flex-col',
144
+ bottom: 'flex-col-reverse',
145
+ left: 'flex-row',
146
+ right: 'flex-row-reverse',
147
+ };
148
+
149
+ export type Mask = string | RegExp | { mask: Mask, definitions?: Record<string, RegExp> };
package/types/table.ts ADDED
@@ -0,0 +1,33 @@
1
+ export interface TableColumn<DataType> {
2
+ id: keyof DataType
3
+ title?: string
4
+ initialWidth?: string | number
5
+ hidden?: boolean
6
+ sorting?: '+' | '-' | undefined
7
+ // Mutually exclusive with onClick
8
+ sortKey?: string
9
+ filterKey?: string
10
+ filterType?: 'filter' | 'fieldSearch'
11
+ // Mutually exclusive with sorting
12
+ onClick?: () => void
13
+ allowResize?: boolean
14
+ filterable?: boolean
15
+ grow?: boolean
16
+ // TODO: support custom filter component
17
+ filterComponent?: (filters: Record<string, string[]>, setFilters: (filters: Record<string, string[]>) => Promise<void>) => string
18
+ }
19
+
20
+ export interface DragItem {
21
+ index: number
22
+ id: string
23
+ type: string
24
+ }
25
+
26
+ export interface PaginationClasses {
27
+ activeIconClasses: string
28
+ inactiveIconClasses: string
29
+ wrapperClasses: string
30
+ resultsClasses: string
31
+ resultsTextClasses: string
32
+ controlClasses: string
33
+ }
@@ -0,0 +1,83 @@
1
+ import type { PresetWind3Theme } from 'unocss';
2
+ import { defineConfig, presetWind3, transformerDirectives } from 'unocss';
3
+ import { presetScrollbar } from 'unocss-preset-scrollbar';
4
+
5
+ type ColorValue = string | Colors;
6
+
7
+ interface Colors {
8
+ [key: string]: ColorValue
9
+ }
10
+
11
+ export default defineConfig({
12
+ // presets
13
+
14
+ // core options
15
+ rules: [],
16
+ content: { pipeline: { include: [/\.(vue|svelte|[jt]sx|vine.ts|mdx?|astro|elm|php|phtml|html|ts)($|\?)/] } },
17
+ presets: [
18
+ presetWind3(),
19
+ presetScrollbar({
20
+ // config
21
+ }),
22
+ ],
23
+ extendTheme: (theme: PresetWind3Theme) => {
24
+ if (!theme.borderRadius) {
25
+ theme.borderRadius = {};
26
+ }
27
+ theme.borderRadius['kvc-button'] = 'var(--kvc-button-borderRadius)'
28
+ theme.borderRadius['kvc-tag'] = 'var(--kvc-tag-borderRadius)'
29
+ theme.borderRadius['kvc-table'] = 'var(--kvc-table-borderRadius)'
30
+ theme.borderRadius['kvc-select'] = 'var(--kvc-select-borderRadius)'
31
+ theme.borderRadius['kvc-modal'] = 'var(--kvc-modal-borderRadius)'
32
+ theme.borderRadius['kvc-tagList'] = 'var(--kvc-tagList-borderRadius)'
33
+ theme.borderRadius['kvc-tagListAdd'] = 'var(--kvc-tagListAdd-borderRadius)'
34
+ theme.borderRadius['kvc-input'] = 'var(--kvc-input-borderRadius)'
35
+ theme.borderRadius['kvc-phoneInput'] = 'var(--kvc-phoneInput-borderRadius)'
36
+ theme.borderRadius['kvc-checkbox'] = 'var(--kvc-checkbox-borderRadius)'
37
+ theme.borderRadius['kvc-textarea'] = 'var(--kvc-textarea-borderRadius)'
38
+ theme.borderRadius['kvc-radioButtonGroup'] = 'var(--kvc-radioButtonGroup-borderRadius)'
39
+ theme.borderRadius['kvc-table'] = 'var(--kvc-table-borderRadius)'
40
+ theme.borderRadius['kvc-tableColumnChooser'] = 'var(--kvc-tableColumnChooser-borderRadius)'
41
+ theme.borderRadius['kvc-tableActions'] = 'var(--kvc-tableActions-borderRadius)'
42
+ },
43
+ theme: {
44
+ colors: {
45
+ 'primary': buildHues('primary'),
46
+ 'secondary': buildHues('secondary'),
47
+ 'tertiary': buildHues('tertiary'),
48
+ 'gray': buildHues('gray'),
49
+ 'success': buildHues('success'),
50
+ 'info': buildHues('info'),
51
+ 'alert': buildHues('alert'),
52
+ 'error': buildHues('error'),
53
+ 'extra': buildHues('extra'),
54
+ 'kvc-table-header': 'var(--kvc-table-header)',
55
+ },
56
+ },
57
+ transformers: [transformerDirectives()],
58
+ });
59
+
60
+ function buildHues(prefix: string) {
61
+ return {
62
+ DEFAULT: `var(--konoma-${prefix}-DEFAULT)`,
63
+ 50: `var(--konoma-${prefix}-50)`,
64
+ 100: `var(--konoma-${prefix}-100)`,
65
+ 150: `var(--konoma-${prefix}-150)`,
66
+ 200: `var(--konoma-${prefix}-200)`,
67
+ 250: `var(--konoma-${prefix}-250)`,
68
+ 300: `var(--konoma-${prefix}-300)`,
69
+ 350: `var(--konoma-${prefix}-350)`,
70
+ 400: `var(--konoma-${prefix}-400)`,
71
+ 450: `var(--konoma-${prefix}-450)`,
72
+ 500: `var(--konoma-${prefix}-500)`,
73
+ 550: `var(--konoma-${prefix}-550)`,
74
+ 600: `var(--konoma-${prefix}-600)`,
75
+ 650: `var(--konoma-${prefix}-650)`,
76
+ 700: `var(--konoma-${prefix}-700)`,
77
+ 750: `var(--konoma-${prefix}-750)`,
78
+ 800: `var(--konoma-${prefix}-800)`,
79
+ 850: `var(--konoma-${prefix}-850)`,
80
+ 900: `var(--konoma-${prefix}-900)`,
81
+ 950: `var(--konoma-${prefix}-950)`,
82
+ }
83
+ }