feat(ui-lib): demo pages for c-lib components
This commit is contained in:
		
							parent
							
								
									e88c1d5f2c
								
							
						
					
					
						commit
						92bd83536f
					
				
							
								
								
									
										5
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -21,16 +21,21 @@ declare module '@vue/runtime-core' { | ||||
|     Bip39Generator: typeof import('./src/tools/bip39-generator/bip39-generator.vue')['default'] | ||||
|     CaseConverter: typeof import('./src/tools/case-converter/case-converter.vue')['default'] | ||||
|     CButton: typeof import('./src/ui/c-button/c-button.vue')['default'] | ||||
|     'CButton.demo': typeof import('./src/ui/c-button/c-button.demo.vue')['default'] | ||||
|     CCard: typeof import('./src/ui/c-card/c-card.vue')['default'] | ||||
|     'CCard.demo': typeof import('./src/ui/c-card/c-card.demo.vue')['default'] | ||||
|     ChmodCalculator: typeof import('./src/tools/chmod-calculator/chmod-calculator.vue')['default'] | ||||
|     Chronometer: typeof import('./src/tools/chronometer/chronometer.vue')['default'] | ||||
|     CLink: typeof import('./src/ui/c-link/c-link.vue')['default'] | ||||
|     'CLink.demo': typeof import('./src/ui/c-link/c-link.demo.vue')['default'] | ||||
|     CollapsibleToolMenu: typeof import('./src/components/CollapsibleToolMenu.vue')['default'] | ||||
|     ColorConverter: typeof import('./src/tools/color-converter/color-converter.vue')['default'] | ||||
|     ColoredCard: typeof import('./src/components/ColoredCard.vue')['default'] | ||||
|     CopyableIpLike: typeof import('./src/tools/ipv4-subnet-calculator/copyable-ip-like.vue')['default'] | ||||
|     CrontabGenerator: typeof import('./src/tools/crontab-generator/crontab-generator.vue')['default'] | ||||
|     DateTimeConverter: typeof import('./src/tools/date-time-converter/date-time-converter.vue')['default'] | ||||
|     'Demo.routes': typeof import('./src/ui/demo/demo.routes.vue')['default'] | ||||
|     DemoWrapper: typeof import('./src/ui/demo/demo-wrapper.vue')['default'] | ||||
|     DeviceInformation: typeof import('./src/tools/device-information/device-information.vue')['default'] | ||||
|     DiffViewer: typeof import('./src/tools/json-diff/diff-viewer/diff-viewer.vue')['default'] | ||||
|     DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default'] | ||||
|  | ||||
| @ -23,9 +23,9 @@ export const config = figue({ | ||||
|     env: { | ||||
|       doc: 'Application current env', | ||||
|       format: 'enum', | ||||
|       values: ['production', 'development', 'test'], | ||||
|       values: ['production', 'development', 'preview', 'test'], | ||||
|       default: 'development', | ||||
|       env: 'MODE', | ||||
|       env: 'VITE_VERCEL_ENV', | ||||
|     }, | ||||
|   }, | ||||
|   plausible: { | ||||
|  | ||||
| @ -4,6 +4,7 @@ import HomePage from './pages/Home.page.vue'; | ||||
| import NotFound from './pages/404.page.vue'; | ||||
| import { tools } from './tools'; | ||||
| import { config } from './config'; | ||||
| import { routes as demoRoutes } from './ui/demo/demo.routes'; | ||||
| 
 | ||||
| const toolsRoutes = tools.map(({ path, name, component, ...config }) => ({ | ||||
|   path, | ||||
| @ -32,6 +33,7 @@ const router = createRouter({ | ||||
|     }, | ||||
|     ...toolsRoutes, | ||||
|     ...toolsRedirectRoutes, | ||||
|     ...(config.app.env === 'development' ? demoRoutes : []), | ||||
|     { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }, | ||||
|   ], | ||||
| }); | ||||
|  | ||||
							
								
								
									
										29
									
								
								src/ui/c-button/c-button.demo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/ui/c-button/c-button.demo.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| <template> | ||||
|   <div v-for="buttonVariant of buttonVariants" :key="buttonVariant"> | ||||
|     <h2>{{ _.capitalize(buttonVariant) }}</h2> | ||||
| 
 | ||||
|     <c-button v-for="buttonType of buttonTypes" :key="buttonType" :variant="buttonVariant" :type="buttonType" mx-1> | ||||
|       Button | ||||
|     </c-button> | ||||
| 
 | ||||
|     <c-button | ||||
|       v-for="buttonType of buttonTypes" | ||||
|       :key="buttonType" | ||||
|       :variant="buttonVariant" | ||||
|       :type="buttonType" | ||||
|       circle | ||||
|       mx-1 | ||||
|     > | ||||
|       A | ||||
|     </c-button> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import _ from 'lodash'; | ||||
| 
 | ||||
| const buttonVariants = ['basic', 'text']; | ||||
| const buttonTypes = ['default', 'primary']; | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped></style> | ||||
| @ -1,240 +1,76 @@ | ||||
| import { darken, lighten } from '../color/color.models'; | ||||
| import { defineThemes } from '../theme/theme.models'; | ||||
| import { appThemes } from '../theme/themes'; | ||||
| 
 | ||||
| export const { useTheme } = defineThemes({ | ||||
|   dark: { | ||||
|     basic: { | ||||
|       default: { | ||||
|         textColor: appThemes.dark.text.baseColor, | ||||
|         backgroundColor: 'rgba(255, 255, 255, 0.08)', | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: 'rgba(255, 255, 255, 0.12)', | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: 'rgba(255, 255, 255, 0.24)', | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.dark.primary.color, | ||||
|         }, | ||||
|       }, | ||||
| 
 | ||||
|       primary: { | ||||
|         textColor: appThemes.dark.text.baseColor, | ||||
|         backgroundColor: appThemes.dark.primary.color, | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.dark.primary.colorHover, | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.dark.primary.colorPressed, | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.dark.primary.color, | ||||
|         }, | ||||
|       }, | ||||
| 
 | ||||
|       warning: { | ||||
|         textColor: appThemes.dark.text.baseColor, | ||||
|         backgroundColor: appThemes.dark.warning.color, | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.dark.warning.colorHover, | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.dark.warning.colorPressed, | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.dark.warning.color, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     text: { | ||||
|       default: { | ||||
|         textColor: appThemes.dark.text.baseColor, | ||||
|         backgroundColor: 'transparent', | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: 'rgba(255, 255, 255, 0.12)', | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: 'rgba(255, 255, 255, 0.82)', | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.dark.primary.color, | ||||
|         }, | ||||
|       }, | ||||
| 
 | ||||
|       primary: { | ||||
|         textColor: appThemes.dark.text.baseColor, | ||||
|         backgroundColor: appThemes.dark.primary.color, | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.dark.primary.colorHover, | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.dark.primary.colorPressed, | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.dark.primary.color, | ||||
|         }, | ||||
|       }, | ||||
| 
 | ||||
|       warning: { | ||||
|         textColor: appThemes.dark.text.baseColor, | ||||
|         backgroundColor: appThemes.dark.warning.color, | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.dark.warning.colorHover, | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.dark.warning.colorPressed, | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.dark.warning.color, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
|   light: { | ||||
|     basic: { | ||||
|       default: { | ||||
|         textColor: appThemes.light.text.baseColor, | ||||
|         backgroundColor: 'rgba(46, 51, 56, 0.05)', | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.light.text.baseColor, | ||||
|           backgroundColor: 'rgba(46, 51, 56, 0.09)', | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.light.text.baseColor, | ||||
|           backgroundColor: 'rgba(46, 51, 56, 0.22)', | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.light.primary.color, | ||||
|         }, | ||||
|       }, | ||||
| 
 | ||||
|       primary: { | ||||
|         textColor: appThemes.dark.text.baseColor, | ||||
|         backgroundColor: appThemes.light.primary.color, | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.light.primary.colorHover, | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.light.primary.colorPressed, | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.light.primary.color, | ||||
|         }, | ||||
|       }, | ||||
| 
 | ||||
|       warning: { | ||||
|         textColor: appThemes.dark.text.baseColor, | ||||
|         backgroundColor: appThemes.light.warning.color, | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.light.warning.colorHover, | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.dark.text.baseColor, | ||||
|           backgroundColor: appThemes.light.warning.colorPressed, | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.light.warning.color, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     text: { | ||||
|       default: { | ||||
|         textColor: appThemes.light.text.baseColor, | ||||
|         backgroundColor: 'transparent', | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.light.text.baseColor, | ||||
|           backgroundColor: 'rgba(46, 51, 56, 0.09)', | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.light.text.baseColor, | ||||
|           backgroundColor: 'rgba(46, 51, 56, 0.13)', | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.light.primary.color, | ||||
|         }, | ||||
|       }, | ||||
|       primary: { | ||||
|         textColor: appThemes.light.primary.color, | ||||
|         backgroundColor: 'transparent', | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.light.primary.colorHover, | ||||
|           backgroundColor: 'rgba(46, 51, 56, 0.09)', | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.light.primary.colorPressed, | ||||
|           backgroundColor: 'rgba(46, 51, 56, 0.13)', | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.light.primary.color, | ||||
|         }, | ||||
|       }, | ||||
|       warning: { | ||||
|         textColor: appThemes.light.warning.color, | ||||
|         backgroundColor: 'transparent', | ||||
| 
 | ||||
|         hover: { | ||||
|           textColor: appThemes.light.warning.colorHover, | ||||
|           backgroundColor: 'rgba(46, 51, 56, 0.09)', | ||||
|         }, | ||||
| 
 | ||||
|         pressed: { | ||||
|           textColor: appThemes.light.warning.colorPressed, | ||||
|           backgroundColor: 'rgba(46, 51, 56, 0.13)', | ||||
|         }, | ||||
| 
 | ||||
|         outline: { | ||||
|           color: appThemes.light.warning.color, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
| const createState = ({ | ||||
|   textColor, | ||||
|   backgroundColor, | ||||
|   hoverBackground, | ||||
|   hoveredTextColor = textColor, | ||||
|   pressedBackground, | ||||
|   pressedTextColor = textColor, | ||||
| }: { | ||||
|   textColor: string; | ||||
|   backgroundColor: string; | ||||
|   hoverBackground: string; | ||||
|   hoveredTextColor?: string; | ||||
|   pressedBackground: string; | ||||
|   pressedTextColor?: string; | ||||
| }) => ({ | ||||
|   textColor, | ||||
|   backgroundColor, | ||||
|   hover: { textColor: hoveredTextColor, backgroundColor: hoverBackground }, | ||||
|   pressed: { textColor: pressedTextColor, backgroundColor: pressedBackground }, | ||||
| }); | ||||
| 
 | ||||
| const createTheme = ({ style }: { style: 'light' | 'dark' }) => { | ||||
|   const theme = appThemes[style]; | ||||
| 
 | ||||
|   return { | ||||
|     basic: { | ||||
|       default: createState({ | ||||
|         textColor: theme.text.baseColor, | ||||
|         backgroundColor: theme.default.color, | ||||
|         hoverBackground: theme.default.colorHover, | ||||
|         pressedBackground: theme.default.colorPressed, | ||||
|       }), | ||||
|       primary: createState({ | ||||
|         textColor: theme.primary.color, | ||||
|         backgroundColor: theme.primary.colorFaded, | ||||
|         hoverBackground: lighten(theme.primary.colorFaded, 30), | ||||
|         pressedBackground: darken(theme.primary.colorFaded, 30), | ||||
|       }), | ||||
|       warning: createState({ | ||||
|         textColor: theme.text.baseColor, | ||||
|         backgroundColor: theme.warning.color, | ||||
|         hoverBackground: theme.warning.colorHover, | ||||
|         pressedBackground: theme.warning.colorPressed, | ||||
|       }), | ||||
|     }, | ||||
|     text: { | ||||
|       default: createState({ | ||||
|         textColor: theme.text.baseColor, | ||||
|         backgroundColor: 'transparent', | ||||
|         hoverBackground: theme.default.colorHover, | ||||
|         pressedBackground: theme.default.colorPressed, | ||||
|       }), | ||||
|       primary: createState({ | ||||
|         textColor: theme.primary.color, | ||||
|         backgroundColor: 'transparent', | ||||
|         hoverBackground: theme.primary.colorFaded, | ||||
|         pressedBackground: darken(theme.primary.colorFaded, 30), | ||||
|       }), | ||||
|       warning: createState({ | ||||
|         textColor: theme.text.baseColor, | ||||
|         backgroundColor: theme.warning.color, | ||||
|         hoverBackground: theme.warning.colorHover, | ||||
|         pressedBackground: theme.warning.colorPressed, | ||||
|       }), | ||||
|     }, | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export const { useTheme } = defineThemes({ | ||||
|   dark: createTheme({ style: 'dark' }), | ||||
|   light: createTheme({ style: 'light' }), | ||||
| }); | ||||
|  | ||||
| @ -14,6 +14,7 @@ | ||||
| <script lang="ts" setup> | ||||
| import type { RouteLocationRaw } from 'vue-router'; | ||||
| import { useTheme } from './c-button.theme'; | ||||
| import { useAppTheme } from '../theme/themes'; | ||||
| 
 | ||||
| const props = withDefaults( | ||||
|   defineProps<{ | ||||
| @ -56,11 +57,11 @@ const tag = computed(() => { | ||||
|   } | ||||
|   return 'button'; | ||||
| }); | ||||
| const appTheme = useAppTheme(); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped> | ||||
| .c-button { | ||||
|   margin: 0; | ||||
|   line-height: 1; | ||||
|   font-family: inherit; | ||||
|   font-size: inherit; | ||||
| @ -103,7 +104,7 @@ const tag = computed(() => { | ||||
|   } | ||||
| 
 | ||||
|   &:focus { | ||||
|     outline: 2px solid v-bind('variantTheme.outline.color'); | ||||
|     outline: 1px solid v-bind('appTheme.primary.color'); | ||||
|   } | ||||
| 
 | ||||
|   &.disabled { | ||||
|  | ||||
							
								
								
									
										13
									
								
								src/ui/c-card/c-card.demo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/ui/c-card/c-card.demo.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <h2>Default</h2> | ||||
| 
 | ||||
|     <c-card title="Title"> | ||||
|       Lorem ipsum, dolor sit amet consectetur adipisicing elit. Repudiandae ipsa reiciendis facilis officia nulla. | ||||
|       Laboriosam cumque molestias excepturi doloribus nulla nemo quod ratione rerum possimus. Excepturi nihil possimus | ||||
|       error itaque. | ||||
|     </c-card> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup></script> | ||||
							
								
								
									
										12
									
								
								src/ui/c-link/c-link.demo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/ui/c-link/c-link.demo.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <h2>Default</h2> | ||||
|     <c-link mx-1> Link </c-link> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import CLink from './c-link.vue'; | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped></style> | ||||
| @ -16,7 +16,15 @@ const props = defineProps<{ | ||||
| const { href, to } = toRefs(props); | ||||
| 
 | ||||
| const theme = useTheme(); | ||||
| const tag = computed(() => (href?.value ? 'a' : RouterLink)); | ||||
| const tag = computed(() => { | ||||
|   if (href?.value) { | ||||
|     return 'a'; | ||||
|   } | ||||
|   if (to?.value) { | ||||
|     return RouterLink; | ||||
|   } | ||||
|   return 'span'; | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped> | ||||
|  | ||||
							
								
								
									
										40
									
								
								src/ui/color/color.models.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/ui/color/color.models.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| import { describe, test, expect } from 'vitest'; | ||||
| import { darken, lighten, setOpacity } from './color.models'; | ||||
| 
 | ||||
| describe('color models', () => { | ||||
|   describe('lighten', () => { | ||||
|     test('lightens a color', () => { | ||||
|       expect(lighten('#000000', 10)).toBe('#0a0a0a'); | ||||
|       expect(lighten('#000000', 20)).toBe('#141414'); | ||||
|       expect(lighten('#ffffff', 30)).toBe('#ffffff'); | ||||
|     }); | ||||
| 
 | ||||
|     test('lightens a color with alpha', () => { | ||||
|       expect(lighten('#00000080', 10)).toBe('#0a0a0a80'); | ||||
|       expect(lighten('#00000080', 20)).toBe('#14141480'); | ||||
|       expect(lighten('#ffffff80', 30)).toBe('#ffffff80'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   describe('darken', () => { | ||||
|     test('darkens a color', () => { | ||||
|       expect(darken('#ffffff', 10)).toBe('#f5f5f5'); | ||||
|       expect(darken('#ffffff', 20)).toBe('#ebebeb'); | ||||
|       expect(darken('#000000', 30)).toBe('#000000'); | ||||
|     }); | ||||
| 
 | ||||
|     test('darkens a color with alpha', () => { | ||||
|       expect(darken('#ffffff80', 10)).toBe('#f5f5f580'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   describe('setOpacity', () => { | ||||
|     test('sets the opacity of a color', () => { | ||||
|       expect(setOpacity('#000000', 0.5)).toBe('#00000080'); | ||||
|     }); | ||||
| 
 | ||||
|     test('sets the opacity of a color with alpha', () => { | ||||
|       expect(setOpacity('#00000000', 0.5)).toBe('#00000080'); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										33
									
								
								src/ui/color/color.models.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/ui/color/color.models.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| export { lighten, darken, setOpacity }; | ||||
| 
 | ||||
| const clampHex = (value: number) => Math.max(0, Math.min(255, Math.round(value))); | ||||
| 
 | ||||
| function lighten(color: string, amount: number): string { | ||||
|   const alpha = color.length === 9 ? color.slice(7) : ''; | ||||
|   const num = parseInt(color.slice(1, 7), 16); | ||||
| 
 | ||||
|   const r = clampHex(((num >> 16) & 255) + amount); | ||||
|   const g = clampHex(((num >> 8) & 255) + amount); | ||||
|   const b = clampHex((num & 255) + amount); | ||||
| 
 | ||||
|   return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, '0')}${alpha}`; | ||||
| } | ||||
| 
 | ||||
| function darken(color: string, amount: number): string { | ||||
|   return lighten(color, -amount); | ||||
| } | ||||
| 
 | ||||
| function setOpacity(color: string, opacity: number): string { | ||||
|   const alpha = clampHex(Math.round(opacity * 255)) | ||||
|     .toString(16) | ||||
|     .padStart(2, '0'); | ||||
| 
 | ||||
|   if (color.length === 7) { | ||||
|     return `${color}${alpha}`; | ||||
|   } | ||||
| 
 | ||||
|   if (color.length === 9) { | ||||
|     return `${color.slice(0, 7)}${alpha}`; | ||||
|   } | ||||
|   throw new Error('Invalid hex color'); | ||||
| } | ||||
							
								
								
									
										33
									
								
								src/ui/demo/demo-wrapper.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/ui/demo/demo-wrapper.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| <template> | ||||
|   <div mt-2 w-full p-8> | ||||
|     <h1>c-lib components</h1> | ||||
| 
 | ||||
|     <div flex> | ||||
|       <div w-30 b-r b-gray b-op-10 b-r-solid pr-4> | ||||
|         <c-button | ||||
|           v-for="{ name } of demoRoutes" | ||||
|           :key="name" | ||||
|           variant="text" | ||||
|           :to="{ name }" | ||||
|           w-full | ||||
|           important:justify-start | ||||
|           :type="route.name === name ? 'primary' : 'default'" | ||||
|         > | ||||
|           {{ name }} | ||||
|         </c-button> | ||||
|       </div> | ||||
| 
 | ||||
|       <div flex-1 pl-4> | ||||
|         <router-view /> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { demoRoutes } from './demo.routes'; | ||||
| 
 | ||||
| const route = useRoute(); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped></style> | ||||
							
								
								
									
										25
									
								
								src/ui/demo/demo.routes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/ui/demo/demo.routes.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| import type { RouteRecordRaw } from 'vue-router'; | ||||
| 
 | ||||
| const demoPages = import.meta.glob('../*/*.demo.vue'); | ||||
| 
 | ||||
| export const demoRoutes = Object.keys(demoPages).map((path) => { | ||||
|   const [, , fileName] = path.split('/'); | ||||
|   const name = fileName.split('.').shift(); | ||||
| 
 | ||||
|   console.log(path); | ||||
| 
 | ||||
|   return { | ||||
|     path: name, | ||||
|     name, | ||||
|     component: () => import(/* @vite-ignore */ path), | ||||
|   } as RouteRecordRaw; | ||||
| }); | ||||
| 
 | ||||
| export const routes = [ | ||||
|   { | ||||
|     path: '/c-lib', | ||||
|     name: 'c-lib', | ||||
|     children: demoRoutes, | ||||
|     component: () => import('./demo-wrapper.vue'), | ||||
|   }, | ||||
| ]; | ||||
| @ -3,16 +3,20 @@ import { defineThemes } from './theme.models'; | ||||
| export const { themes: appThemes, useTheme: useAppTheme } = defineThemes({ | ||||
|   light: { | ||||
|     text: { | ||||
|       baseColor: 'rgb(51, 54, 57)', | ||||
|       mutedColor: 'rgba(118, 124, 130)', | ||||
|       baseColor: '#333639', | ||||
|       mutedColor: '#767c82', | ||||
|     }, | ||||
|     default: { | ||||
|       color: 'rgba(46, 51, 56, 0.05)', | ||||
|       colorHover: 'rgba(46, 51, 56, 0.09)', | ||||
|       colorPressed: 'rgba(46, 51, 56, 0.22)', | ||||
|     }, | ||||
| 
 | ||||
|     primary: { | ||||
|       color: '#18a058', | ||||
|       colorHover: '#1ea54c', | ||||
|       colorPressed: '#0C7A43', | ||||
|       colorFaded: '#18a0582f', | ||||
|     }, | ||||
| 
 | ||||
|     warning: { | ||||
|       color: '#f59e0b', | ||||
|       colorHover: '#f59e0b', | ||||
| @ -33,14 +37,19 @@ export const { themes: appThemes, useTheme: useAppTheme } = defineThemes({ | ||||
|   }, | ||||
|   dark: { | ||||
|     text: { | ||||
|       baseColor: 'rgba(255, 255, 255, 0.82)', | ||||
|       mutedColor: 'rgba(255, 255, 255, 0.5)', | ||||
|       baseColor: '#ffffffd1', | ||||
|       mutedColor: '#ffffff80', | ||||
|     }, | ||||
|     default: { | ||||
|       color: 'rgba(255, 255, 255, 0.08)', | ||||
|       colorHover: 'rgba(255, 255, 255, 0.12)', | ||||
|       colorPressed: 'rgba(255, 255, 255, 0.24)', | ||||
|     }, | ||||
| 
 | ||||
|     primary: { | ||||
|       color: '#1ea54c', | ||||
|       colorHover: '#36AD6A', | ||||
|       colorPressed: '#0C7A43', | ||||
|       colorFaded: '#18a0582f', | ||||
|     }, | ||||
|     warning: { | ||||
|       color: '#f59e0b', | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user