@bobbykim/manguito-theme 0.2.0 → 0.4.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.
- package/README.md +1 -1
- package/index.ts +29 -4
- package/lib/collapse/Collapse.vue +85 -0
- package/lib/collapse/index.types.ts +3 -0
- package/lib/directives/index.ts +57 -0
- package/lib/dropdown/DropdownContainer.vue +47 -0
- package/lib/dropdown/DropdownContent.vue +70 -0
- package/lib/dropdown/index.types.ts +4 -0
- package/package.json +2 -2
- package/theme/index.ts +128 -70
- package/theme/theme.ts +86 -80
- package/theme/theme.types.ts +1 -0
- package/themeVariables.cjs +94 -1
package/README.md
CHANGED
package/index.ts
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
|
-
import GenerateMCLClass
|
|
2
|
-
|
|
1
|
+
import GenerateMCLClass, {
|
|
2
|
+
colorType,
|
|
3
|
+
textType,
|
|
4
|
+
borderWidthType,
|
|
5
|
+
scaleType,
|
|
6
|
+
} from './theme'
|
|
7
|
+
import type { ClassType, InputType } from './theme/index.js'
|
|
8
|
+
// base components
|
|
9
|
+
import DropdownContainer from './lib/dropdown/DropdownContainer.vue'
|
|
10
|
+
import DropdownContent from './lib/dropdown/DropdownContent.vue'
|
|
11
|
+
import Collapse from './lib/collapse/Collapse.vue'
|
|
12
|
+
import type { CollapseEvent } from './lib/collapse/index.types'
|
|
3
13
|
|
|
4
14
|
const generateClass = (type: ClassType, value: InputType): string => {
|
|
5
15
|
const mclGenerate = new GenerateMCLClass(type, value)
|
|
6
|
-
|
|
7
|
-
|
|
16
|
+
if ((<string[]>(<unknown>colorType)).includes(type)) {
|
|
17
|
+
return mclGenerate.generateColorClass()
|
|
18
|
+
}
|
|
19
|
+
if ((<string[]>(<unknown>textType)).includes(type)) {
|
|
20
|
+
return mclGenerate.generateTextClass()
|
|
21
|
+
}
|
|
22
|
+
if ((<string[]>(<unknown>borderWidthType)).includes(type)) {
|
|
23
|
+
return mclGenerate.generateBorderWidthClass()
|
|
24
|
+
}
|
|
25
|
+
if ((<string[]>(<unknown>scaleType)).includes(type)) {
|
|
26
|
+
return mclGenerate.generateScaleClass()
|
|
27
|
+
}
|
|
28
|
+
// return spacing type if all of above is false
|
|
29
|
+
return mclGenerate.generateSpacingClass()
|
|
8
30
|
}
|
|
9
31
|
|
|
10
32
|
export default generateClass
|
|
33
|
+
|
|
34
|
+
export { DropdownContainer, DropdownContent, Collapse, CollapseEvent }
|
|
35
|
+
export * from './lib/directives'
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
|
|
3
|
+
import type { CollapseEvent } from './index.types'
|
|
4
|
+
const props = withDefaults(
|
|
5
|
+
defineProps<{
|
|
6
|
+
collapseId: string
|
|
7
|
+
accordion?: string
|
|
8
|
+
className?: string
|
|
9
|
+
visible?: boolean
|
|
10
|
+
}>(),
|
|
11
|
+
{
|
|
12
|
+
className: '',
|
|
13
|
+
visible: false,
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
const emit = defineEmits(['toggle'])
|
|
17
|
+
const toggle = ref<boolean>(props.visible)
|
|
18
|
+
const contentRef = ref<HTMLAreaElement>()
|
|
19
|
+
const slotHeight = ref<number>()
|
|
20
|
+
|
|
21
|
+
const handleToggleEvent = (e: Event): void => {
|
|
22
|
+
toggle.value = !toggle.value
|
|
23
|
+
emit('toggle', { ...e, visible: toggle.value } as CollapseEvent)
|
|
24
|
+
}
|
|
25
|
+
const initObserver = (): ResizeObserver => {
|
|
26
|
+
const observer = new ResizeObserver(() => {
|
|
27
|
+
if (contentRef.value) {
|
|
28
|
+
slotHeight.value = contentRef.value.scrollHeight
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
slotHeight.value = 0
|
|
32
|
+
})
|
|
33
|
+
return observer
|
|
34
|
+
}
|
|
35
|
+
const slotHeightVal = computed(() => {
|
|
36
|
+
return {
|
|
37
|
+
height: contentRef.value && toggle.value ? slotHeight.value + 'px' : '0px',
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
watch(
|
|
41
|
+
() => props.visible,
|
|
42
|
+
(newValue) => {
|
|
43
|
+
toggle.value = newValue
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
// lifecycle hooks
|
|
47
|
+
onMounted(() => {
|
|
48
|
+
if (typeof window !== undefined) {
|
|
49
|
+
initObserver().observe(contentRef.value as Element)
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
onBeforeUnmount(() => {
|
|
53
|
+
initObserver().disconnect()
|
|
54
|
+
})
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<template>
|
|
58
|
+
<div>
|
|
59
|
+
<button
|
|
60
|
+
:id="collapseId"
|
|
61
|
+
@click="handleToggleEvent"
|
|
62
|
+
class="hidden"
|
|
63
|
+
:accordion="accordion"
|
|
64
|
+
:visible="toggle"
|
|
65
|
+
></button>
|
|
66
|
+
<div
|
|
67
|
+
class="overflow-hidden transition-[height] duration-500"
|
|
68
|
+
:style="slotHeightVal"
|
|
69
|
+
:class="[toggle ? 'ease-in' : 'ease-out']"
|
|
70
|
+
>
|
|
71
|
+
<div
|
|
72
|
+
ref="contentRef"
|
|
73
|
+
class="transition-opacity duration-500"
|
|
74
|
+
:class="[
|
|
75
|
+
toggle ? 'opacity-100 ease-in' : 'opacity-0 ease-out',
|
|
76
|
+
className,
|
|
77
|
+
]"
|
|
78
|
+
>
|
|
79
|
+
<slot />
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</template>
|
|
84
|
+
|
|
85
|
+
<style scoped></style>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Directive } from 'vue'
|
|
2
|
+
|
|
3
|
+
export const vClickOutside: Directive = {
|
|
4
|
+
mounted(el, binding) {
|
|
5
|
+
el.__ClickOutsideHandler = (event: Event) => {
|
|
6
|
+
if (!(el === event.target || el.contains(event.target))) {
|
|
7
|
+
binding.value(event)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
document.body.addEventListener('click', el.__ClickOutsideHandler)
|
|
11
|
+
},
|
|
12
|
+
unmounted(el) {
|
|
13
|
+
document.body.removeEventListener('click', el.__ClickOutsideHandler)
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const vCollapse: Directive = {
|
|
18
|
+
mounted(el, binding) {
|
|
19
|
+
el.__HandleToggler = (event: Event): void => {
|
|
20
|
+
const eTarget = event.target as HTMLElement
|
|
21
|
+
let target: HTMLElement
|
|
22
|
+
if (eTarget.tagName === 'A') {
|
|
23
|
+
const targetId = eTarget.getAttribute('href')
|
|
24
|
+
const formattedTargetId =
|
|
25
|
+
targetId?.charAt(0) === '#' ? targetId.substring(1) : targetId
|
|
26
|
+
target = document.getElementById(
|
|
27
|
+
formattedTargetId as string
|
|
28
|
+
) as HTMLElement
|
|
29
|
+
} else {
|
|
30
|
+
target = document.getElementById(binding.arg as string) as HTMLElement
|
|
31
|
+
}
|
|
32
|
+
if (!target.hasAttribute('accordion')) {
|
|
33
|
+
// run when it is not accordion component case
|
|
34
|
+
target.click()
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
const accordionName = target.getAttribute('accordion')
|
|
38
|
+
const accordionList: NodeListOf<HTMLElement> = document.querySelectorAll(
|
|
39
|
+
`button[accordion="${accordionName}"]`
|
|
40
|
+
)
|
|
41
|
+
// loop through each accordion items and handle reaction for each case
|
|
42
|
+
for (let i = 0; i < accordionList.length; i++) {
|
|
43
|
+
const isVisible = accordionList[i].getAttribute('visible')
|
|
44
|
+
if (accordionList[i].id !== target.id && isVisible === 'true') {
|
|
45
|
+
accordionList[i].click()
|
|
46
|
+
}
|
|
47
|
+
if (accordionList[i].id === target.id) {
|
|
48
|
+
accordionList[i].click()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
el.addEventListener('click', el.__HandleToggler)
|
|
53
|
+
},
|
|
54
|
+
unmounted(el) {
|
|
55
|
+
el.removeEventListener('click', el.__HandleToggler)
|
|
56
|
+
},
|
|
57
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { reactive, provide, ref, onMounted } from 'vue'
|
|
3
|
+
import type { InjectType } from './index.types'
|
|
4
|
+
import { vClickOutside } from '../directives'
|
|
5
|
+
|
|
6
|
+
const emit = defineEmits(['click-outside', 'toggle'])
|
|
7
|
+
const dropdownTarget = ref()
|
|
8
|
+
const dropdownState = reactive<InjectType>({
|
|
9
|
+
active: false,
|
|
10
|
+
buttonHeight: 0,
|
|
11
|
+
})
|
|
12
|
+
provide('dropdownState', dropdownState)
|
|
13
|
+
const toggle = (e: Event): void => {
|
|
14
|
+
dropdownState.active = !dropdownState.active
|
|
15
|
+
emit('toggle', e)
|
|
16
|
+
}
|
|
17
|
+
const onClickOutside = (e: Event): void => {
|
|
18
|
+
dropdownState.active = false
|
|
19
|
+
emit('click-outside', e)
|
|
20
|
+
}
|
|
21
|
+
const onEscape = (): void => {
|
|
22
|
+
dropdownState.active = false
|
|
23
|
+
}
|
|
24
|
+
onMounted(() => {
|
|
25
|
+
if (typeof window !== undefined) {
|
|
26
|
+
dropdownState.buttonHeight = dropdownTarget.value.scrollHeight
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<div
|
|
33
|
+
class="relative"
|
|
34
|
+
ref="dropdownTarget"
|
|
35
|
+
v-click-outside="onClickOutside"
|
|
36
|
+
@keyup.esc="onEscape"
|
|
37
|
+
>
|
|
38
|
+
<slot
|
|
39
|
+
name="toggler"
|
|
40
|
+
:toggle="toggle"
|
|
41
|
+
:dropdown-state="dropdownState.active"
|
|
42
|
+
/>
|
|
43
|
+
<slot></slot>
|
|
44
|
+
</div>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref, inject, Transition } from 'vue'
|
|
3
|
+
import { InjectType } from './index.types'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(
|
|
6
|
+
defineProps<{
|
|
7
|
+
className?: string
|
|
8
|
+
}>(),
|
|
9
|
+
{
|
|
10
|
+
className: '',
|
|
11
|
+
}
|
|
12
|
+
)
|
|
13
|
+
const contentRef = ref<HTMLAreaElement>()
|
|
14
|
+
const dropdownState = inject<InjectType>('dropdownState', {
|
|
15
|
+
active: false,
|
|
16
|
+
buttonHeight: 0,
|
|
17
|
+
})
|
|
18
|
+
const active = computed<boolean>(() => {
|
|
19
|
+
return dropdownState.active
|
|
20
|
+
})
|
|
21
|
+
const handleItemClick = () => {
|
|
22
|
+
dropdownState.active = false
|
|
23
|
+
}
|
|
24
|
+
const buttonHeight = computed(() => {
|
|
25
|
+
return { '--button-height': `${dropdownState.buttonHeight}px` }
|
|
26
|
+
})
|
|
27
|
+
const dropdownDirection = computed<string | undefined>(() => {
|
|
28
|
+
if (typeof window === undefined) {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
if (!dropdownState.active || !contentRef.value) {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
if (
|
|
35
|
+
window.innerHeight - contentRef.value.getBoundingClientRect().bottom <
|
|
36
|
+
0
|
|
37
|
+
) {
|
|
38
|
+
return 'dropup-bottom'
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<transition name="dropdown-content">
|
|
45
|
+
<div
|
|
46
|
+
v-if="active"
|
|
47
|
+
ref="contentRef"
|
|
48
|
+
class="absolute my-2xs max-w-[14rem] w-max overflow-hidden"
|
|
49
|
+
:class="[dropdownDirection, className]"
|
|
50
|
+
:style="buttonHeight"
|
|
51
|
+
>
|
|
52
|
+
<slot :item-click="handleItemClick" />
|
|
53
|
+
</div>
|
|
54
|
+
</transition>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<style scoped lang="scss">
|
|
58
|
+
.dropup-bottom {
|
|
59
|
+
bottom: var(--button-height);
|
|
60
|
+
}
|
|
61
|
+
.dropdown-content-enter-active,
|
|
62
|
+
.dropdown-content-leave-active {
|
|
63
|
+
transition: all 0.3s;
|
|
64
|
+
}
|
|
65
|
+
.dropdown-content-enter-from,
|
|
66
|
+
.dropdown-content-leave-to {
|
|
67
|
+
opacity: 0;
|
|
68
|
+
transform: translateY(-10px);
|
|
69
|
+
}
|
|
70
|
+
</style>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobbykim/manguito-theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "main theme file for manguito components library. Other MCL components will need to import this file to run.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
"url": "https://github.com/bobbykim89/manguito-component-library.git"
|
|
18
18
|
},
|
|
19
19
|
"license": "MIT",
|
|
20
|
-
"gitHead": "
|
|
20
|
+
"gitHead": "79700f8b34204a6ecbe2f56d75f74a64c331055c"
|
|
21
21
|
}
|
package/theme/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import MCLTheme from './theme'
|
|
1
|
+
import MCLTheme from './theme.js'
|
|
2
2
|
import type {
|
|
3
3
|
ColorPalette,
|
|
4
4
|
HeadingSize,
|
|
@@ -16,68 +16,83 @@ import type {
|
|
|
16
16
|
* @Export GenerateMCLClass - extends MCLTheme class
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
19
|
+
export const colorType = [
|
|
20
|
+
'BGCOLOR',
|
|
21
|
+
'BEFOREBG',
|
|
22
|
+
'AFTERBG',
|
|
23
|
+
'HVBGCOLOR',
|
|
24
|
+
'FCBGCOLOR',
|
|
25
|
+
'ACTIVEBG',
|
|
26
|
+
'TEXTCOLOR',
|
|
27
|
+
'HVTEXTCOLOR',
|
|
28
|
+
'DISABLEDTEXTCOLOR',
|
|
29
|
+
'SVGFILL',
|
|
30
|
+
'RINGCOLOR',
|
|
31
|
+
'FOCUSRING',
|
|
32
|
+
'ACTIVERING',
|
|
33
|
+
'OFFSETRING',
|
|
34
|
+
'DUMMYCOLOR',
|
|
35
|
+
'BTNCOLOR',
|
|
36
|
+
'LISTCOLOR',
|
|
37
|
+
'BORDER',
|
|
38
|
+
'BORDERX',
|
|
39
|
+
'BORDERY',
|
|
40
|
+
'BORDERT',
|
|
41
|
+
'BORDERB',
|
|
42
|
+
'BORDERL',
|
|
43
|
+
'BORDERR',
|
|
44
|
+
] as const
|
|
45
|
+
|
|
46
|
+
export const textType = [
|
|
47
|
+
'H1',
|
|
48
|
+
'H2',
|
|
49
|
+
'H3',
|
|
50
|
+
'H4',
|
|
51
|
+
'BODYTEXT',
|
|
52
|
+
'FONTWEIGHT',
|
|
53
|
+
'TEXTALIGN',
|
|
54
|
+
] as const
|
|
55
|
+
export const borderWidthType = [
|
|
56
|
+
'BORDERW',
|
|
57
|
+
'BORDERXW',
|
|
58
|
+
'BORDERYW',
|
|
59
|
+
'BORDERTW',
|
|
60
|
+
'BORDERBW',
|
|
61
|
+
'BORDERLW',
|
|
62
|
+
'BORDERRW',
|
|
63
|
+
] as const
|
|
64
|
+
export const scaleType = ['BGOPACITY', 'OPACITY'] as const
|
|
65
|
+
export const spacingType = [
|
|
66
|
+
'MARGIN',
|
|
67
|
+
'MARGINX',
|
|
68
|
+
'MARGINY',
|
|
69
|
+
'MARGINT',
|
|
70
|
+
'MARGINB',
|
|
71
|
+
'MARGINL',
|
|
72
|
+
'MARGINR',
|
|
73
|
+
'PADDING',
|
|
74
|
+
'PADDINGX',
|
|
75
|
+
'PADDINGY',
|
|
76
|
+
'PADDINGT',
|
|
77
|
+
'PADDINGB',
|
|
78
|
+
'PADDINGL',
|
|
79
|
+
'PADDINGR',
|
|
80
|
+
'GAP',
|
|
81
|
+
] as const
|
|
82
|
+
const allType = [
|
|
83
|
+
...colorType,
|
|
84
|
+
...textType,
|
|
85
|
+
...borderWidthType,
|
|
86
|
+
...scaleType,
|
|
87
|
+
...spacingType,
|
|
88
|
+
] as const
|
|
89
|
+
|
|
90
|
+
export type ClassType = (typeof allType)[number]
|
|
91
|
+
export type ColorClassType = (typeof colorType)[number]
|
|
92
|
+
export type TextClassType = (typeof textType)[number]
|
|
93
|
+
export type BorderWidthClassType = (typeof borderWidthType)[number]
|
|
94
|
+
export type ScaleClassType = (typeof scaleType)[number]
|
|
95
|
+
export type SpacingClassType = (typeof spacingType)[number]
|
|
81
96
|
|
|
82
97
|
export type InputType =
|
|
83
98
|
| ColorPalette
|
|
@@ -98,13 +113,15 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
98
113
|
this.classType = classType
|
|
99
114
|
this.classValue = classValue
|
|
100
115
|
}
|
|
101
|
-
|
|
116
|
+
// handle color classes types
|
|
117
|
+
generateColorClass(): string {
|
|
102
118
|
switch (this.classType) {
|
|
103
|
-
// case: color class
|
|
104
119
|
case 'BGCOLOR':
|
|
105
120
|
return this.getBgColorClass()
|
|
106
121
|
case 'HVBGCOLOR':
|
|
107
122
|
return this.getHoverBgColorClass()
|
|
123
|
+
case 'FCBGCOLOR':
|
|
124
|
+
return this.getFocusBgColorClass()
|
|
108
125
|
case 'BEFOREBG':
|
|
109
126
|
return this.getBeforeBgColorClass()
|
|
110
127
|
case 'AFTERBG':
|
|
@@ -125,11 +142,12 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
125
142
|
return this.getFocusRingColorClass()
|
|
126
143
|
case 'ACTIVERING':
|
|
127
144
|
return this.getActiveRingColorClass()
|
|
145
|
+
case 'OFFSETRING':
|
|
146
|
+
return this.getRingOffsetColorClass()
|
|
128
147
|
case 'BTNCOLOR':
|
|
129
148
|
return this.getBtnColorClass()
|
|
130
149
|
case 'LISTCOLOR':
|
|
131
150
|
return this.getRingColorClass()
|
|
132
|
-
// case: border color class
|
|
133
151
|
case 'BORDER':
|
|
134
152
|
return this.getBorderColorClass()
|
|
135
153
|
case 'BORDERX':
|
|
@@ -144,6 +162,13 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
144
162
|
return this.getBorderLeftColorClass()
|
|
145
163
|
case 'BORDERR':
|
|
146
164
|
return this.getBorderRightColorClass()
|
|
165
|
+
default:
|
|
166
|
+
return ' '
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// handle text class types
|
|
170
|
+
generateTextClass(): string {
|
|
171
|
+
switch (this.classType) {
|
|
147
172
|
// case: heading text class
|
|
148
173
|
case 'H1':
|
|
149
174
|
return this.getH1Class()
|
|
@@ -162,6 +187,13 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
162
187
|
// case: text alignment class
|
|
163
188
|
case 'TEXTALIGN':
|
|
164
189
|
return this.getTextAlignClass()
|
|
190
|
+
default:
|
|
191
|
+
return ' '
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// handle border width class types
|
|
195
|
+
generateBorderWidthClass(): string {
|
|
196
|
+
switch (this.classType) {
|
|
165
197
|
// case: border width class
|
|
166
198
|
case 'BORDERW':
|
|
167
199
|
return this.getBorderWidthClass()
|
|
@@ -177,13 +209,24 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
177
209
|
return this.getBorderLeftWidthClass()
|
|
178
210
|
case 'BORDERRW':
|
|
179
211
|
return this.getBorderWidthClass()
|
|
212
|
+
default:
|
|
213
|
+
return ' '
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
generateScaleClass(): string {
|
|
217
|
+
switch (this.classType) {
|
|
180
218
|
// case: opacity class
|
|
181
219
|
case 'OPACITY':
|
|
182
220
|
return this.getOpacityClass()
|
|
183
221
|
case 'BGOPACITY':
|
|
184
222
|
return this.getBgOpacityClass()
|
|
185
|
-
|
|
186
|
-
|
|
223
|
+
default:
|
|
224
|
+
return ' '
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
generateSpacingClass(): string {
|
|
228
|
+
switch (this.classType) {
|
|
229
|
+
// case: margins
|
|
187
230
|
case 'MARGIN':
|
|
188
231
|
return this.getMarginClass()
|
|
189
232
|
case 'MARGINX':
|
|
@@ -198,7 +241,7 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
198
241
|
return this.getMarginLeftClass()
|
|
199
242
|
case 'MARGINR':
|
|
200
243
|
return this.getMarginRightClass()
|
|
201
|
-
// paddings
|
|
244
|
+
// case: paddings
|
|
202
245
|
case 'PADDING':
|
|
203
246
|
return this.getPaddingClass()
|
|
204
247
|
case 'PADDINGX':
|
|
@@ -213,7 +256,7 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
213
256
|
return this.getPaddingLeftClass()
|
|
214
257
|
case 'PADDINGR':
|
|
215
258
|
return this.getPaddingRightClass()
|
|
216
|
-
// gap
|
|
259
|
+
// case: gap
|
|
217
260
|
case 'GAP':
|
|
218
261
|
return this.getGapClass()
|
|
219
262
|
default:
|
|
@@ -234,6 +277,12 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
234
277
|
}
|
|
235
278
|
return MCLTheme.hoverBgColor[this.classValue as ColorPalette]
|
|
236
279
|
}
|
|
280
|
+
getFocusBgColorClass(): string {
|
|
281
|
+
if (!this.validateColorType) {
|
|
282
|
+
return ' '
|
|
283
|
+
}
|
|
284
|
+
return MCLTheme.focusBgColor[this.classValue as ColorPalette]
|
|
285
|
+
}
|
|
237
286
|
getBeforeBgColorClass(): string {
|
|
238
287
|
if (!this.validateColorType) {
|
|
239
288
|
return ' '
|
|
@@ -297,6 +346,12 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
297
346
|
}
|
|
298
347
|
return MCLTheme.ringActiveColor[this.classValue as ColorPalette]
|
|
299
348
|
}
|
|
349
|
+
getRingOffsetColorClass(): string {
|
|
350
|
+
if (!this.validateColorType) {
|
|
351
|
+
return ' '
|
|
352
|
+
}
|
|
353
|
+
return MCLTheme.ringOffsetColor[this.classValue as ColorPalette]
|
|
354
|
+
}
|
|
300
355
|
// btn & list
|
|
301
356
|
getBtnColorClass(): string {
|
|
302
357
|
if (!this.validateColorType) {
|
|
@@ -604,6 +659,9 @@ class GenerateMCLClass extends MCLTheme {
|
|
|
604
659
|
}
|
|
605
660
|
return validatorRe.test(this.classValue)
|
|
606
661
|
}
|
|
662
|
+
dummyMethod(): any {
|
|
663
|
+
return this.getRingOffsetColorClass()
|
|
664
|
+
}
|
|
607
665
|
}
|
|
608
666
|
|
|
609
667
|
export default GenerateMCLClass
|
package/theme/theme.ts
CHANGED
|
@@ -3,93 +3,40 @@
|
|
|
3
3
|
* @Interface - Classes for color, header text, body text, border color, border width(top, left).
|
|
4
4
|
* @Export RDSTheme - an abstract class
|
|
5
5
|
*/
|
|
6
|
+
import type {
|
|
7
|
+
ColorPalette,
|
|
8
|
+
HeadingSize,
|
|
9
|
+
BodyText,
|
|
10
|
+
FontWeight,
|
|
11
|
+
Range,
|
|
12
|
+
OpacityRange,
|
|
13
|
+
SpacingLevel,
|
|
14
|
+
Position,
|
|
15
|
+
} from './theme.types'
|
|
6
16
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
secondary: string
|
|
10
|
-
success: string
|
|
11
|
-
info: string
|
|
12
|
-
warning: string
|
|
13
|
-
danger: string
|
|
14
|
-
'light-1': string
|
|
15
|
-
'light-2': string
|
|
16
|
-
'light-3': string
|
|
17
|
-
'light-4': string
|
|
18
|
-
'dark-1': string
|
|
19
|
-
'dark-2': string
|
|
20
|
-
'dark-3': string
|
|
21
|
-
'dark-4': string
|
|
22
|
-
black: string
|
|
23
|
-
white: string
|
|
24
|
-
transparent: string
|
|
17
|
+
export type ColorClass = {
|
|
18
|
+
[key in ColorPalette]: string
|
|
25
19
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
sm: string
|
|
29
|
-
md: string
|
|
30
|
-
lg: string
|
|
31
|
-
xl: string
|
|
20
|
+
export type HeaderSizeClass = {
|
|
21
|
+
[key in HeadingSize]: string
|
|
32
22
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
xs: string
|
|
36
|
-
sm: string
|
|
37
|
-
md: string
|
|
38
|
-
lg: string
|
|
39
|
-
xl: string
|
|
23
|
+
export type BodyTextClass = {
|
|
24
|
+
[key in BodyText]: string
|
|
40
25
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
light: string
|
|
44
|
-
normal: string
|
|
45
|
-
bold: string
|
|
26
|
+
export type FontWeightClass = {
|
|
27
|
+
[key in FontWeight]: string
|
|
46
28
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
1: string
|
|
50
|
-
2: string
|
|
51
|
-
3: string
|
|
52
|
-
4: string
|
|
53
|
-
5: string
|
|
54
|
-
6: string
|
|
55
|
-
7: string
|
|
56
|
-
8: string
|
|
57
|
-
9: string
|
|
58
|
-
10: string
|
|
59
|
-
11: string
|
|
60
|
-
12: string
|
|
29
|
+
export type BorderWidth = {
|
|
30
|
+
[key in Range<1, 12>]: string
|
|
61
31
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
10: string
|
|
65
|
-
20: string
|
|
66
|
-
30: string
|
|
67
|
-
40: string
|
|
68
|
-
50: string
|
|
69
|
-
60: string
|
|
70
|
-
70: string
|
|
71
|
-
80: string
|
|
72
|
-
90: string
|
|
73
|
-
100: string
|
|
32
|
+
export type Opacity = {
|
|
33
|
+
[key in OpacityRange]: string
|
|
74
34
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
'0': string
|
|
78
|
-
'3xs': string
|
|
79
|
-
'2xs': string
|
|
80
|
-
xs: string
|
|
81
|
-
sm: string
|
|
82
|
-
md: string
|
|
83
|
-
lg: string
|
|
84
|
-
xl: string
|
|
85
|
-
'2xl': string
|
|
86
|
-
'3xl': string
|
|
35
|
+
export type Spacing = {
|
|
36
|
+
[key in SpacingLevel]: string
|
|
87
37
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
left: string
|
|
91
|
-
center: string
|
|
92
|
-
right: string
|
|
38
|
+
export type Alignment = {
|
|
39
|
+
[key in Position]: string
|
|
93
40
|
}
|
|
94
41
|
|
|
95
42
|
abstract class MCLTheme {
|
|
@@ -113,7 +60,7 @@ abstract class MCLTheme {
|
|
|
113
60
|
white: 'bg-white',
|
|
114
61
|
transparent: 'bg-transparent',
|
|
115
62
|
}
|
|
116
|
-
// hover bg color class
|
|
63
|
+
// hover: bg color class
|
|
117
64
|
protected static hoverBgColor: ColorClass = {
|
|
118
65
|
primary: 'hover:bg-primary',
|
|
119
66
|
secondary: 'hover:bg-secondary',
|
|
@@ -133,6 +80,26 @@ abstract class MCLTheme {
|
|
|
133
80
|
white: 'hover:bg-white',
|
|
134
81
|
transparent: 'hover:bg-transparent',
|
|
135
82
|
}
|
|
83
|
+
// focus: bg color class
|
|
84
|
+
protected static focusBgColor: ColorClass = {
|
|
85
|
+
primary: 'focus:bg-primary',
|
|
86
|
+
secondary: 'focus:bg-secondary',
|
|
87
|
+
success: 'focus:bg-success',
|
|
88
|
+
danger: 'focus:bg-danger',
|
|
89
|
+
info: 'focus:bg-info',
|
|
90
|
+
warning: 'focus:bg-warning',
|
|
91
|
+
'light-1': 'focus:bg-light-1',
|
|
92
|
+
'light-2': 'focus:bg-light-2',
|
|
93
|
+
'light-3': 'focus:bg-light-3',
|
|
94
|
+
'light-4': 'focus:bg-light-4',
|
|
95
|
+
'dark-1': 'focus:bg-dark-1',
|
|
96
|
+
'dark-2': 'focus:bg-dark-2',
|
|
97
|
+
'dark-3': 'focus:bg-dark-3',
|
|
98
|
+
'dark-4': 'focus:bg-dark-4',
|
|
99
|
+
black: 'focus:bg-black',
|
|
100
|
+
white: 'focus:bg-white',
|
|
101
|
+
transparent: 'focus:bg-transparent',
|
|
102
|
+
}
|
|
136
103
|
// ::before bg color class
|
|
137
104
|
protected static beforeBgColor: ColorClass = {
|
|
138
105
|
primary: 'before:bg-primary',
|
|
@@ -333,6 +300,45 @@ abstract class MCLTheme {
|
|
|
333
300
|
white: 'active:ring-white',
|
|
334
301
|
transparent: 'active:ring-transparent',
|
|
335
302
|
}
|
|
303
|
+
// ring-offset color class
|
|
304
|
+
protected static ringOffsetColor: ColorClass = {
|
|
305
|
+
primary: 'ring-offset-primary',
|
|
306
|
+
secondary: 'ring-offset-secondary',
|
|
307
|
+
success: 'ring-offset-success',
|
|
308
|
+
danger: 'ring-offset-danger',
|
|
309
|
+
info: 'ring-offset-info',
|
|
310
|
+
warning: 'ring-offset-warning',
|
|
311
|
+
'light-1': 'ring-offset-light-1',
|
|
312
|
+
'light-2': 'ring-offset-light-2',
|
|
313
|
+
'light-3': 'ring-offset-light-3',
|
|
314
|
+
'light-4': 'ring-offset-light-4',
|
|
315
|
+
'dark-1': 'ring-offset-dark-1',
|
|
316
|
+
'dark-2': 'ring-offset-dark-2',
|
|
317
|
+
'dark-3': 'ring-offset-dark-3',
|
|
318
|
+
'dark-4': 'ring-offset-dark-4',
|
|
319
|
+
black: 'ring-offset-black',
|
|
320
|
+
white: 'ring-offset-white',
|
|
321
|
+
transparent: 'ring-offset-transparent',
|
|
322
|
+
}
|
|
323
|
+
protected static dummyColor: ColorClass = {
|
|
324
|
+
primary: 'ring-offset-primary',
|
|
325
|
+
secondary: 'ring-offset-secondary',
|
|
326
|
+
success: 'ring-offset-success',
|
|
327
|
+
danger: 'ring-offset-danger',
|
|
328
|
+
info: 'ring-offset-info',
|
|
329
|
+
warning: 'ring-offset-warning',
|
|
330
|
+
'light-1': 'ring-offset-light-1',
|
|
331
|
+
'light-2': 'ring-offset-light-2',
|
|
332
|
+
'light-3': 'ring-offset-light-3',
|
|
333
|
+
'light-4': 'ring-offset-light-4',
|
|
334
|
+
'dark-1': 'ring-offset-dark-1',
|
|
335
|
+
'dark-2': 'ring-offset-dark-2',
|
|
336
|
+
'dark-3': 'ring-offset-dark-3',
|
|
337
|
+
'dark-4': 'ring-offset-dark-4',
|
|
338
|
+
black: 'ring-offset-black',
|
|
339
|
+
white: 'ring-offset-white',
|
|
340
|
+
transparent: 'ring-offset-transparent',
|
|
341
|
+
}
|
|
336
342
|
// btn color class
|
|
337
343
|
protected static btnColor: ColorClass = {
|
|
338
344
|
primary: 'btn-primary',
|
package/theme/theme.types.ts
CHANGED
|
@@ -57,6 +57,7 @@ export type Range<T extends number, R extends number> = IntRange<
|
|
|
57
57
|
_RangeArray<T>,
|
|
58
58
|
R
|
|
59
59
|
>
|
|
60
|
+
|
|
60
61
|
export type ButtonSize = 'small' | 'medium' | 'large'
|
|
61
62
|
export type OpacityRange = 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100
|
|
62
63
|
export type Directions = 'left' | 'right'
|
package/themeVariables.cjs
CHANGED
|
@@ -4,7 +4,6 @@ const mclTheme = plugin.withOptions(
|
|
|
4
4
|
() => {
|
|
5
5
|
return ({ addBase, theme, addComponents, addUtilities, e }) => {
|
|
6
6
|
const colors = theme('colors')
|
|
7
|
-
// console.log(colors)
|
|
8
7
|
const listColors = Object.keys(colors).reduce((accumulator, key) => {
|
|
9
8
|
if (typeof colors[key] === 'string') {
|
|
10
9
|
return {
|
|
@@ -29,6 +28,34 @@ const mclTheme = plugin.withOptions(
|
|
|
29
28
|
),
|
|
30
29
|
}
|
|
31
30
|
}, {})
|
|
31
|
+
const linkColors = Object.keys(colors).reduce((accumulator, key) => {
|
|
32
|
+
const invalidKeys = ['current', 'transparent', 'inherit']
|
|
33
|
+
if (invalidKeys.includes(key)) {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
if (typeof colors[key] === 'string') {
|
|
37
|
+
return {
|
|
38
|
+
...accumulator,
|
|
39
|
+
[`.mcl-link.text-${e(key)}`]: {
|
|
40
|
+
'&:hover': {
|
|
41
|
+
[`@apply text-${key}/60`]: {},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const colorShades = Object.keys(colors[key])
|
|
47
|
+
return {
|
|
48
|
+
...accumulator,
|
|
49
|
+
...colorShades.reduce((acc, level) => ({
|
|
50
|
+
...acc,
|
|
51
|
+
[`.mcl-link.text-${e(key)}-${level}`]: {
|
|
52
|
+
'&:hover': {
|
|
53
|
+
[`@apply text-${key}-${level}/60`]: {},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
})),
|
|
57
|
+
}
|
|
58
|
+
})
|
|
32
59
|
const btnColors = Object.keys(colors).reduce((accumulator, key) => {
|
|
33
60
|
if (typeof colors[key] === 'string') {
|
|
34
61
|
return {
|
|
@@ -56,6 +83,18 @@ const mclTheme = plugin.withOptions(
|
|
|
56
83
|
'@apply ring-0': {},
|
|
57
84
|
},
|
|
58
85
|
},
|
|
86
|
+
[`.btn.btn-${e(key)}.btn-no-ring`]: {
|
|
87
|
+
'&:focus': {
|
|
88
|
+
'@apply ring-0': {},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
[`.btn.btn-progress.btn-${e(key)}`]: {
|
|
92
|
+
[`@apply before:bg-${key} border-${key} text-${key} bg-transparent`]:
|
|
93
|
+
{},
|
|
94
|
+
'&:hover, &:focus': {
|
|
95
|
+
'@apply text-white': {},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
59
98
|
}
|
|
60
99
|
}
|
|
61
100
|
|
|
@@ -90,6 +129,13 @@ const mclTheme = plugin.withOptions(
|
|
|
90
129
|
'@apply ring-0': {},
|
|
91
130
|
},
|
|
92
131
|
},
|
|
132
|
+
[`.btn.btn-progress.btn-${e(key)}-${level}`]: {
|
|
133
|
+
[`@apply before:bg-${key}-${level} border-${key}-${level} text-${key}-${level} bg-transparent`]:
|
|
134
|
+
{},
|
|
135
|
+
'&:hover, &:focus': {
|
|
136
|
+
'@apply text-white': {},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
93
139
|
}),
|
|
94
140
|
{}
|
|
95
141
|
),
|
|
@@ -252,6 +298,10 @@ const mclTheme = plugin.withOptions(
|
|
|
252
298
|
'.mcl-link': {
|
|
253
299
|
color: theme('colors.primary'),
|
|
254
300
|
textDecoration: 'underline',
|
|
301
|
+
'@apply transition-colors duration-200 ease-in': {},
|
|
302
|
+
'&:hover': {
|
|
303
|
+
'@apply text-primary/60': {},
|
|
304
|
+
},
|
|
255
305
|
},
|
|
256
306
|
'.mcl-list': {
|
|
257
307
|
'list-style-position': 'inside',
|
|
@@ -319,16 +369,59 @@ const mclTheme = plugin.withOptions(
|
|
|
319
369
|
'@apply ring-0': {},
|
|
320
370
|
},
|
|
321
371
|
},
|
|
372
|
+
'.btn.btn-no-ring': {
|
|
373
|
+
'@apply ring-offset-0': {},
|
|
374
|
+
'&:focus': {
|
|
375
|
+
'@apply ring-0': {},
|
|
376
|
+
},
|
|
377
|
+
},
|
|
322
378
|
'.btn.btn-invert': {
|
|
323
379
|
'@apply border-2 border-primary text-primary bg-white': {},
|
|
324
380
|
'&:hover': {
|
|
325
381
|
'@apply bg-primary text-white bg-opacity-100': {},
|
|
326
382
|
},
|
|
327
383
|
},
|
|
384
|
+
'.btn.btn-progress': {
|
|
385
|
+
position: 'relative',
|
|
386
|
+
'&::before': {
|
|
387
|
+
content: '""',
|
|
388
|
+
position: 'absolute',
|
|
389
|
+
height: '100%',
|
|
390
|
+
width: '0',
|
|
391
|
+
bottom: '0',
|
|
392
|
+
left: '0',
|
|
393
|
+
transition: 'width 300ms linear',
|
|
394
|
+
},
|
|
395
|
+
'@apply before:bg-primary border-2 border-primary text-primary bg-transparent':
|
|
396
|
+
{},
|
|
397
|
+
},
|
|
398
|
+
'.btn.btn-progress > *': {
|
|
399
|
+
position: 'relative',
|
|
400
|
+
},
|
|
401
|
+
'.btn.btn-progress.btn-progress-r': {
|
|
402
|
+
'&::before': {
|
|
403
|
+
left: '100%',
|
|
404
|
+
transition: 'all 300ms linear',
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
'.btn.btn-progress:hover, .btn.btn-progress:focus': {
|
|
408
|
+
'@apply text-white': {},
|
|
409
|
+
'&::before': {
|
|
410
|
+
width: '100%',
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
'.btn.btn-progress.btn-progress-r:hover, .btn.btn-progress.btn-progress-r:focus':
|
|
414
|
+
{
|
|
415
|
+
'&::before': {
|
|
416
|
+
width: '100%',
|
|
417
|
+
left: '0',
|
|
418
|
+
},
|
|
419
|
+
},
|
|
328
420
|
})
|
|
329
421
|
|
|
330
422
|
addUtilities(listColors)
|
|
331
423
|
addUtilities(btnColors)
|
|
424
|
+
addUtilities(linkColors)
|
|
332
425
|
}
|
|
333
426
|
},
|
|
334
427
|
(options = {}) => {
|